使用ReentrantLock实现同步
ReentrantLock对象的lock()方法获取锁, 调用unlock()方法释放锁
调用ReentrantLock对象的lock()方法的线程就持有"对象监视器",其他线程只有等待锁被释放时再次争抢。效果和使用synchronized关键字一样。
关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式, 类ReentrantLock也可以实现同样的功能,但需要借助于Condition对象。Condition类是再jdk5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能。使用ReentrantLock结合Condition类是可以实现"选择性通知",这个功能非常重要。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MySservice {
private ReentrantLock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private boolean hasValue = false;
public void set(){
try {
lock.lock();
while(hasValue == true){
System.out.println("setsetsetset"+Thread.currentThread().getName());
conditionA.await();
}
System.out.println("set");
hasValue = true;
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void get(){
try {
lock.lock();
while(hasValue == false){
System.out.println("getgetgetget");
conditionB.await();
}
System.out.println("get");
hasValue = false;
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class MyThreadA extends Thread {
private MySservice mySservice;
public MyThreadA(MySservice mySservice){
super();
this.mySservice = mySservice;
}
@Override
public void run(){
for (int i = 0; i < Integer.MAX_VALUE; i++) {
mySservice.set();
}
}
}
public class MyThreadB extends Thread {
private MySservice mySservice;
public MyThreadB(MySservice mySservice){
super();
this.mySservice = mySservice;
}
@Override
public void run(){
for (int i = 0; i < Integer.MAX_VALUE; i++) {
mySservice.get();
}
}
}
public class Run {
public static void main(String[] args) {
MySservice mySservice = new MySservice();
MyThreadA[] myThreadA = new MyThreadA[10];
MyThreadB[] myThreadB = new MyThreadB[10];
for (int i = 0; i < 10; i++) {
myThreadA[i] = new MyThreadA(mySservice);
myThreadB[i] = new MyThreadB(mySservice);
myThreadA[i].setName((i+1)+"");
myThreadA[i].start();
myThreadB[i].start();
}
}
}
方法getHoldCount()
该方法是查询当前线程保持此锁定的个数,也就是调用lock()方法的次数
import java.util.concurrent.locks.ReentrantLock;
public class Service {
private ReentrantLock lock = new ReentrantLock();
public void serviceMethod1(){
try{
lock.lock();
System.out.println("serviceMethod1 getHoldCount="
+lock.getHoldCount());
serviceMethod2();
}finally {
lock.unlock();
}
}
public void serviceMethod2(){
try{
lock.lock();
System.out.println("serviceMethod2 getHoldCount="
+lock.getHoldCount());
}finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
service.serviceMethod1();
}
}
方法getQueueLength()
返回正等待获取此锁定的线程估计数。
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.serviceMethod1();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
System.out.println("有线程树:"+service.lock.getQueueLength()+"正在等待锁!");
}
}
import java.util.concurrent.locks.ReentrantLock;
public class Service {
public ReentrantLock lock = new ReentrantLock();
public void serviceMethod1(){
try{
lock.lock();
System.out.println("ThreadName="+Thread.currentThread().getName()+" 进入方法!");
Thread.sleep(1000);
}catch(InterruptedException ex){
ex.printStackTrace();
}finally {
lock.unlock();
}
}
}
方法hasQueuedThread(), hasQueuedThreads()
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
public ReentrantLock lock = new ReentrantLock();
public Condition newCondition = lock.newCondition();
public void waitMethod(){
try{
lock.lock();
Thread.sleep(Integer.MAX_VALUE);
}catch (InterruptedException ex){
ex.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread threadA = new Thread(runnable);
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnable);
threadB.start();
Thread.sleep(500);
System.out.println(service.lock.hasQueuedThread(threadA));
System.out.println(service.lock.hasQueuedThread(threadB));
System.out.println(service.lock.hasQueuedThreads());
System.out.println(service.lock.getQueueLength());
}
}
方法isFair()
判断是不是公平锁
import java.util.concurrent.locks.ReentrantLock;
public class Service {
private ReentrantLock lock;
public Service(boolean isFair){
super();
lock = new ReentrantLock(isFair);
}
public void serviceMethod(){
try{
lock.lock();
System.out.println(Thread.currentThread().getName()+" 公平锁情况:"+lock.isFair());
}finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) {
Service service1 = new Service(true);
Runnable runnable = new Runnable() {
@Override
public void run() {
service1.serviceMethod();
}
};
Thread t1 = new Thread(runnable,"A");
t1.start();
Service service2 = new Service(false);
Runnable runnable2 = new Runnable() {
@Override
public void run() {
service2.serviceMethod();
}
};
Thread t2 = new Thread(runnable2,"B");
t2.start();
}
}
方法isHeldByCurrentThread()
查询当前线程是否保持此锁定
import java.util.concurrent.locks.ReentrantLock;
public class Service {
private ReentrantLock lock;
public Service(){
super();
lock = new ReentrantLock();
}
public void serviceMethod(){
try{
System.out.println("当前线程是否保持此锁定"+lock.isHeldByCurrentThread());
lock.lock();
System.out.println("当前线程是否保持此锁定"+lock.isHeldByCurrentThread());
}finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) {
final Service service1 = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service1.serviceMethod();
}
};
Thread t = new Thread(runnable);
t.start();
}
}
方法tryLock(long timeout, TimeUnit unit)
如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private ReentrantLock lock = new ReentrantLock();
public void waitMethod(){
try{
if(lock.tryLock(3, TimeUnit.SECONDS)){
System.out.println(" "+Thread.currentThread().getName()
+"获得锁的时间:"+System.currentTimeMillis());
Thread.sleep(10000);
}else{
System.out.println(" "+Thread.currentThread().getName()
+"没有获得锁");
}
}catch (InterruptedException ex){
ex.printStackTrace();
}finally {
if(lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
public class Run {
public static void main(String[] args) {
final MyService service = new MyService();
Runnable runnableRef = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+" 调用waitMethod时间: "+System.currentTimeMillis());
service.waitMethod();
}
};
Thread threadA = new Thread(runnableRef);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnableRef);
threadB.setName("B");
threadB.start();
}
}