简介

java多线程中可以使用synchronized关键字来实现线程间同步互斥,但在jdk1.5中新增加了ReentrantLock类也能实现同样的效果,并且在扩展功能上也更加强大,比如具有嗅探锁定、多路通知分支等功能,并且使用上比synchronized更加灵活。

如何使用ReentrantLock

主要是lock.lock()和lock.unlock()两个方法

 public class MyService implements Runnable {

     protected ReentrantLock lock;

     public MyService(ReentrantLock lock){
this.lock = lock;
} public void run() {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.unlock();
} }
 /**
* 测试类
* @author ko
*
*/
public class Test { public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
for (int i = 0; i < 4; i++) {
new Thread(new MyService(lock)).start();
}
}
}
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
Thread-3 0
Thread-3 1
Thread-3 2
Thread-3 3
Thread-3 4

使用Condition类实现wait、notify的功能

Condition类也是jdk1.5里出来的,它能实现synchronized和wait、notify搭配的功能,另外比后者更灵活,Condition可以实现多路通知功能,也就是在一个Lock对象里可以创建多个Condition(即对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择的进行线程通知,在调度线程上更加灵活

而synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在这个对象上。线程开始notifyAll时,需要通知所有的WAITING线程,没有选择权,会有相当大的效率问题。

使用Condition为什么会报java.lang.IllegalMonitorStateException异常

还是刚才的代码,稍作改动

 public class MyService implements Runnable {

     protected ReentrantLock lock;
protected Condition condition; public MyService(ReentrantLock lock,Condition condition){
this.lock = lock;
this.condition = condition;
} public void run() {
// lock.lock();
try {
condition.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// lock.unlock();
} }
 /**
* 测试类
* @author ko
*
*/
public class Test { public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
for (int i = 0; i < 4; i++) {
new Thread(new MyService(lock,condition)).start();
}
}
}
Exception in thread "Thread-0" Exception in thread "Thread-1" Exception in thread "Thread-2" Exception in thread "Thread-3" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
at ww.MyService.run(MyService.java:26)
at java.lang.Thread.run(Unknown Source)

  报错的异常信息是监视器出错,原因是在调用condition.await()之前是要先调用lock.lock()来获得同步监视器。

正确使用Condition类

 public class MyService implements Runnable {

     protected ReentrantLock lock;
protected Condition condition; public MyService(ReentrantLock lock,Condition condition){
this.lock = lock;
this.condition = condition;
} public void await(){
try {
lock.lock();
System.out.println("await time is "+System.currentTimeMillis());
condition.await();
System.out.println("after await info...");
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
lock.unlock();
}
} public void signal(){
try {
lock.lock();
System.out.println("signal time is "+System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
} public void run() {
await();
} }
 /**
* 测试类
* @author ko
*
*/
public class Test { public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
MyService service = new MyService(lock,condition);
new Thread(service).start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.signal();
}
}
await time is 1501142954379
signal time is 1501142957381
after await info...

 成功实现等待通知模式,整理一下,下表的方法功能是对应的

Object类

Condition类

Wait()

Await()

Wait(long timeout)

Await(long time,TimeUnit unit)

Notify()

Signal()

notifyAll()

signalAll()

使用多个Condition实现通知部分线程

 public class MyService implements Runnable {

     protected ReentrantLock lock;
protected Condition conditionA;
protected Condition conditionB; public MyService(ReentrantLock lock,Condition conditionA,Condition conditionB){
this.lock = lock;
this.conditionA = conditionA;
this.conditionB = conditionB;
} public void await_A(){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+" await_A time is "+System.currentTimeMillis());
conditionA.await();
System.out.println(Thread.currentThread().getName()+" after await_A info...");
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
lock.unlock();
}
} public void await_B(){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+" await_B time is "+System.currentTimeMillis());
conditionB.await();
System.out.println(Thread.currentThread().getName()+" after_B await info...");
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
lock.unlock();
}
} public void signal_A(){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+" signal_A time is "+System.currentTimeMillis());
conditionA.signal();
} finally {
lock.unlock();
}
} public void signal_B(){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+" signal_B time is "+System.currentTimeMillis());
conditionB.signal();
} finally {
lock.unlock();
}
} public void run() {
String tname = Thread.currentThread().getName();
if (tname.equals("A")) {
await_A();
} else if (tname.equals("B")) {
await_B();
}
} }
 /**
* 测试类
* @author ko
*
*/
public class Test { public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock(); Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
MyService service = new MyService(lock,conditionA,conditionB); Thread tA = new Thread(service);
tA.setName("A");
tA.start(); Thread tB = new Thread(service);
tB.setName("B");
tB.start(); try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} service.signal_A();
}
}
A await_A time is 1501482321344
B await_B time is 1501482321346
main signal_A time is 1501482324344
A after await_A info...

可以看到只唤醒了A线程。。。

一对一的生产者消费者  

 /**
* 生产者和消费者一对一
* @author ko
*
*/
public class MyService { protected ReentrantLock lock = new ReentrantLock();
protected Condition condition = lock.newCondition();
protected boolean hasValue = false; public void set(){
try {
lock.lock();
while (hasValue == true) {
condition.await();
}
System.out.println("★");
hasValue = true;
condition.signal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
} public void get(){
try {
lock.lock();
while (hasValue == false) {
condition.await();
}
System.out.println("☆");
hasValue = false;
condition.signal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
} }
 /**
* 生产者
* @author ko
*
*/
public class Producer implements Runnable { protected MyService myService; public Producer(MyService myService) {
super();
this.myService = myService;
} public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
myService.set();
}
} }
 /**
* 消费者
* @author ko
*
*/
public class Customer implements Runnable { protected MyService myService; public Customer(MyService myService) {
super();
this.myService = myService;
} public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
myService.get();
}
} }
 /**
* 测试类
* @author ko
*
*/
public class Test { public static void main(String[] args) {
MyService myService = new MyService();
Producer p = new Producer(myService);
Customer c = new Customer(myService); new Thread(p).start();
new Thread(c).start(); }
}

打印结果

多对多的生产者消费者

 /**
* 测试类
* @author ko
*
*/
public class Test { public static void main(String[] args) {
MyService myService = new MyService(); for (int i = 0; i < 10; i++) {
new Thread(new Producer(myService)).start();
new Thread(new Customer(myService)).start();
} }
}
 /**
* 生产者和消费者多对多
* @author ko
*
*/
public class MyService { protected ReentrantLock lock = new ReentrantLock();
protected Condition condition = lock.newCondition();
protected boolean hasValue = false; public void set(){
try {
lock.lock();
while (hasValue == true) {
System.out.println("有可能★连续打印");
condition.await();
}
System.out.println("★");
hasValue = true;
condition.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
} public void get(){
try {
lock.lock();
while (hasValue == false) {
System.out.println("有可能☆连续打印");
condition.await();
}
System.out.println("☆");
hasValue = false;
condition.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
} }

要注意的是由于现在是多个生产者消费者,所以condition.signal()要改为condition.signalAll(),其它代码不变。

查看打印结果,发现★和☆总是间隔打印,但是 有可能★连续打印 和 有可能☆连续打印 却有可能连续打印,这是因为改为signalAll后唤醒的是所有线程,有可能再次把自己唤醒,所以会出现这种情况。

公平锁与非公平锁

公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,而非公平锁是一种抢占机制,随机的。

还是上面的代码,给ReentrantLock换个有isFair参数的构造方法,new ReentrantLock(isFair) true就是公平锁,false就是非公平锁。再给打印的语句加上线程名,当为true时,线程是按顺序打印,为false时随机打印。

方法getHoldCount()的使用

getHoldCount()表示当前线程获取锁的个数

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(true);
public void method1(){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+"线程保持lock锁的个数:"+lock.getHoldCount()+" method1");
method2();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void method2(){
try {
lock.lock();
System.out.println(Thread.currentThread().getName()+"线程保持lock锁的个数:"+lock.getHoldCount()+" method2");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
 public class ThreadA extends Thread {

     protected MyService myService;

     public ThreadA(MyService myService) {
super();
this.myService = myService;
} public void run() {
myService.method1();
} }
 public class Test {
public static void main(String[] args) {
MyService myService = new MyService();
new ThreadA(myService).start();
}
}

getQueueLength()方法使用

getQueueLength()表示等待获取lock锁的估计线程个数。

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(); public void getql(){
System.out.println("等待获取lock锁的估计线程个数:"+lock.getQueueLength()+" method1");
} public void synmethod(){
System.out.println(Thread.currentThread().getName()+"开始了。。。");
lock.lock();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
 public class ThreadA extends Thread {
protected MyService myService; public ThreadA(MyService myService) {
super();
this.myService = myService;
} public void run() {
myService.synmethod();
}
}
 public class Test {
public static void main(String[] args) {
MyService myService = new MyService();
new ThreadA(myService).start();
new ThreadA(myService).start();
new ThreadA(myService).start();
new ThreadA(myService).start();
new ThreadA(myService).start();
while (true) {
myService.getql();
try {
Thread.sleep(900);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

getWaitQueueLength(condition)的用法

getWaitQueueLength(condition) 表示返回等待与此锁相关的给定条件condition的线程估计数。比如有3个线程都执行了同一个condition的await方法,那么调用getWaitQueueLength(condition)返回的就是3.

 public class MyService {
protected ReentrantLock lock = new ReentrantLock();
protected Condition condition = lock.newCondition();
protected Condition condition1 = lock.newCondition(); public void synmethod(){
System.out.println(Thread.currentThread().getName()+"开始了。。。");
lock.lock();
System.out.println("进入lock锁与condition关联的的估计线程个数:"+lock.getWaitQueueLength(condition));
System.out.println("进入lock锁与condition1关联的的估计线程个数:"+lock.getWaitQueueLength(condition1));
System.out.println("");
try {
if (!Thread.currentThread().getName().contains("2")) {
condition.await();
}else{
condition1.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
 public class Test {
public static void main(String[] args) {
MyService myService = new MyService();
new ThreadA(myService).start();
new ThreadA(myService).start();
new ThreadA(myService).start();
new ThreadA(myService).start();
new ThreadA(myService).start();
}
}

hasQueuedThread(thread)和hasQueuedThreads()的使用

hasQueuedThread(thread)返回的是线程thread是否在等待获取lock锁

hasQueuedThreads()返回的是是否有线程正在等待获取lock锁

 public class MyService {
protected ReentrantLock lock = new ReentrantLock();
protected Condition condition = lock.newCondition(); public void hasa(Thread thread){
if (lock.hasQueuedThread(thread)) {
System.out.println(thread.getName()+"正在等待获取lock锁。。。");
}else{
System.out.println(thread.getName()+"不在等待获取lock锁。。。");
}
System.out.println("是否有线程在等待获取lock锁:"+lock.hasQueuedThreads());
System.out.println("");
} public void synmethod(){
System.out.println(Thread.currentThread().getName()+"开始了。。。");
lock.lock(); if (Thread.currentThread().getName().contains("1")) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
}
 public class Test {
public static void main(String[] args) {
MyService myService = new MyService();
ThreadA ta = new ThreadA(myService);
ta.start();
ThreadA tb = new ThreadA(myService);
tb.start();
while (true) {
myService.hasa(ta);
myService.hasa(tb);
System.out.println(""+ta.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

hasWaiters(condition)的用法

hasWaiters(condition)表示是否有线程进入了lock锁与condition相关联的等待中。

 public class MyService {
protected ReentrantLock lock = new ReentrantLock();
protected Condition condition = lock.newCondition(); public void synmethod(){
System.out.println(Thread.currentThread().getName()+"开始了。。。");
lock.lock(); System.out.println("是否有线程进入了lock锁与condition相关联的等待中:"+lock.hasWaiters(condition));
if (Thread.currentThread().getName().contains("0")) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
 public class Test {
public static void main(String[] args) {
MyService myService = new MyService(); ThreadA ta = new ThreadA(myService);
ta.start(); try {
Thread.sleep(3500);
} catch (InterruptedException e) {
e.printStackTrace();
} ThreadA tb = new ThreadA(myService);
tb.start(); }
}

方法isFair()、isHeldByCurrentThread()、isLocked()的使用

isFair()判断线程锁是不是公平锁

isHeldByCurrentThread()查询当前线程是否保持此锁定

isLocked()查询此锁定是否由任意线程保持

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(true);
protected Condition condition = lock.newCondition(); public void synmethod(){
System.out.println("lock锁是不是公平锁:"+lock.isFair());
System.out.println("lock锁定是否由任意线程保持:"+lock.isLocked());
System.out.println(Thread.currentThread().getName()+"是否保持lock锁定:"+lock.isHeldByCurrentThread());
lock.lock();
System.out.println("lock锁定是否由任意线程保持:"+lock.isLocked());
System.out.println(Thread.currentThread().getName()+"是否保持lock锁定:"+lock.isHeldByCurrentThread());
lock.unlock();
}
}
 public class Test {
public static void main(String[] args) {
MyService myService = new MyService(); ThreadA ta = new ThreadA(myService);
ta.start();
}
}

lockInterruptibly()方法的使用

lockInterruptibly()比lock()获取锁之前多了个判断,如果当前线程未被中断,则获取锁定,如果已被中断,则抛出java.lang.InterruptedException异常。

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(true);
protected Condition condition = lock.newCondition(); public void synmethod(){
try {
System.out.println(Thread.currentThread().getName()+" begin "+new Date().toString());
for (int i = 0; i < Integer.MAX_VALUE/20; i++) {// 大概会延长7 8s,这里不用sleep延长线程时间,而是这样写,是因为调用线程的interrupt()方法时,如果线程在sleep会报异常
Math.random();
}
if(new Random().nextInt(5)%2==0){// 随机
System.out.println(Thread.currentThread().getName()+" 使用的是lock() ");
lock.lock();
}else{
System.out.println(Thread.currentThread().getName()+" 使用的是lockInterruptibly() ");
lock.lockInterruptibly();
} System.out.println(Thread.currentThread().getName()+" lock 1 "+new Date().toString());
for (int i = 0; i < Integer.MAX_VALUE/20; i++) {// 同上
Math.random();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName()+" lock 2 "+new Date().toString());
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
System.out.println(Thread.currentThread().getName()+" end "+new Date().toString());
}
}
}
 /**
* 测试类
* @author ko
*
*/
public class Test {
public static void main(String[] args) {
MyService myService = new MyService(); ThreadA taa = new ThreadA(myService);
taa.setName("taa");
taa.start(); try {
Thread.sleep(1500);// 等前面的线程都启动好
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("taa interrupt "+new Date().toString());
taa.interrupt();// 打标记 这个时候taa还没有进入lock锁里 }
}

代码里采用了随机的处理,有的时候使用的是lock(),有的时候使用的是lockInterruptibly(),多运行几遍就能得到两种结果。

lock.tryLock()、lock.tryLock(timeout, unit)方法使用

lock.tryLock())  立即返回,获得锁返回true,没获得锁返回false

lock.tryLock(3, TimeUnit.SECONDS) 等待3s,3s后,获得锁返回true,没获得锁返回false

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(true);
protected Condition condition = lock.newCondition(); public void synmethod(){
try {
System.out.println(Thread.currentThread().getName()+"进入方法"+new Date().toString()); if (lock.tryLock()) {// 立即返回,获得锁返回true,没获得锁返回false
System.out.println(Thread.currentThread().getName()+"获得锁");
} else {
System.out.println(Thread.currentThread().getName()+"没有获得锁");
} // if (lock.tryLock(3, TimeUnit.SECONDS)) {// 等待3s,3s后,获得锁返回true,没获得锁返回false
// System.out.println(Thread.currentThread().getName()+"获得锁的时间"+new Date().toString());
// Thread.sleep(10000);
// } else {
// System.out.println(Thread.currentThread().getName()+"没有获得锁");
// } System.out.println(Thread.currentThread().getName()+"方法结束"+new Date().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
 /**
* 测试类
* @author ko
*
*/
public class Test {
public static void main(String[] args) {
MyService myService = new MyService(); ThreadA ta = new ThreadA(myService);
ta.setName("ta");
ta.start(); ThreadA taa = new ThreadA(myService);
taa.setName("taa");
taa.start();
}
}

awaitUninterruptibly()方法使用

当在线程等待的时候,如果外部要中断该线程,不会报InterruptedException异常,而await()会报异常

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(true);
protected Condition condition = lock.newCondition(); public void synmethod(){
try {
System.out.println(Thread.currentThread().getName()+"进入方法"+new Date().toString()); lock.lock(); if (new Random().nextInt(5)%2 == 0) {
System.out.println(Thread.currentThread().getName()+"走的是await()");
condition.await();
} else {
System.out.println(Thread.currentThread().getName()+"走的是awaitUninterruptibly()");
condition.awaitUninterruptibly();
} } catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName()+"方法结束"+new Date().toString());
lock.unlock();
}
}
}
 /**
* 测试类
* @author ko
*
*/
public class Test {
public static void main(String[] args) {
MyService myService = new MyService(); ThreadA taa = new ThreadA(myService);
taa.setName("taa");
taa.start(); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
taa.interrupt();// 打标记
}
}

awaitUntil(Time time)方法使用

awaitUntil(Time time)和await()一样会使当前线程进入等待状态,不过它有个截止时间,到了time这个时间,自动唤醒。

 public class MyService {
protected ReentrantLock lock = new ReentrantLock(true);
protected Condition condition = lock.newCondition(); public void synmethod(){
try {
System.out.println(Thread.currentThread().getName()+"进入方法"+new Date().toString()); lock.lock(); Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 10);
System.out.println("begin awaitUntil "+new Date().toString());
condition.awaitUntil(calendar.getTime());//
System.out.println("after awaitUntil "+new Date().toString()); } catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName()+"方法结束"+new Date().toString());
lock.unlock();
}
}
}
 /**
* 测试类
* @author ko
*
*/
public class Test {
public static void main(String[] args) {
MyService myService = new MyService(); ThreadA taa = new ThreadA(myService);
taa.setName("taa");
taa.start();
}
}

使用Condition实现顺序执行

 /**
* 利用condition实现顺序执行
* @author ko
*
*/
public class MyService implements Runnable{
protected ReentrantLock lock;
protected Condition signalCondition;// 在某个线程里负责等待
protected Condition awaitCondition;// 在某个线程里负责唤醒 public MyService(ReentrantLock lock, Condition signalCondition, Condition awaitCondition) {
super();
this.lock = lock;
this.signalCondition = signalCondition;
this.awaitCondition = awaitCondition;
} public void print(Condition signalCondition, Condition awaitCondition) throws InterruptedException{
lock.lock();
for (int j = 0; j < 10; j++) {
for (int i = 1; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
System.out.println("");
signalCondition.signal();
awaitCondition.await();
}
lock.unlock();
} public void run() {
try {
print(signalCondition, awaitCondition);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

myservice

 /**
* 测试类
* @author ko
*
*/
public class Test {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition(); MyService myService = new MyService(lock, conditionB, conditionA); new Thread(new MyService(lock, conditionB, conditionA),"thread a").start();
new Thread(new MyService(lock, conditionC, conditionB),"thread b").start();
new Thread(new MyService(lock, conditionA, conditionC),"thread c").start(); }
}

test

thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3 thread a 1
thread a 2
thread a 3 thread b 1
thread b 2
thread b 3 thread c 1
thread c 2
thread c 3

打印结果

java并发之ReentrantLock学习理解的更多相关文章

  1. Java并发之ReentrantLock源码解析(四)

    Condition 在上一章中,我们大概了解了Condition的使用,下面我们来看看Condition再juc的实现.juc下Condition本质上是一个接口,它只定义了这个接口的使用方式,具体的 ...

  2. Java并发之ReentrantLock

    一.ReentrantLock简介 ReentrantLock字面意义上理解为可重入锁.那么怎么理解可重入这个概念呢?或者说和我们经常用的synchronized又什么区别呢? ReentrantLo ...

  3. Java并发之ReentrantLock详解

    一.入题 ReentrantLock是Java并发包中互斥锁,它有公平锁和非公平锁两种实现方式,以lock()为例,其使用方式为: ReentrantLock takeLock = new Reent ...

  4. Java并发之ReentrantLock源码解析(一)

    ReentrantLock ReentrantLock是一种可重入的互斥锁,它的行为和作用与关键字synchronized有些类似,在并发场景下可以让多个线程按照一定的顺序访问同一资源.相比synch ...

  5. Java并发之ReentrantLock源码解析(三)

    ReentrantLock和BlockingQueue 首先,看到这个标题,不要怀疑自己进错文章,也不要怀疑笔者写错,哈哈.本章笔者会从BlockingQueue(阻塞队列)的角度,看看juc包下的阻 ...

  6. java高并发----个人学习理解汇总记录

    1.首先,需要理解几个概念 1.同步(Synchronous):同步方法调用一旦开始,调用者必须等到前面的方法调用返回后,才能继续后续的行为,依次直到完成所有. 2.异步(Asynchronous): ...

  7. Java并发之ReentrantLock源码解析(二)

    在了解如何加锁时候,我们再来了解如何解锁.可重入互斥锁ReentrantLock的解锁方法unlock()并不区分是公平锁还是非公平锁,Sync类并没有实现release(int arg)方法,这里会 ...

  8. 深入理解Java并发之synchronized实现原理

    深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...

  9. Java 8 Lambda表达式学习和理解

    Java 8 Lambda表达式和理解 说明:部分资料来源于网络 时间:20190704 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性.Lambda 允许把函数作为一 ...

随机推荐

  1. 《java入门第一季》之面向对象面试题(this和super的区别)

    this和super的区别? 分别是什么呢? this代表本类对象的引用. super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员) 怎么用呢? A:调用成员变量 this.成员变量 ...

  2. SpriteBuilder全屏弹出菜单的特殊效果

    但是等一下!这里可以有更多.对于全屏的弹出菜单,你可以在显示弹出全屏菜单时朦胧化背景的level视图. 通过修改SpriteBuilder中的color节点的Color属性(比如修改为black)和O ...

  3. PS 滤镜算法原理——染色玻璃

    %%%% 完成PS 中的染色玻璃滤镜特效 clc; clear all; close all; Image=imread('4.jpg'); Image=double(Image); Gray_Ima ...

  4. 关于masm中PTR伪指令的一点思考

    在masm中,PTR伪指令只能修饰内存变量类型,因为任何寄存器的大小都是已知的且不能改变的(如果PTR修饰的是寄存器,则它修饰的是寄存器本身而不是其指向的内容)所以不能用PTR改变寄存器的大小,例如: ...

  5. obj-c编程16:键值编码(KVC)

    我们可以借助obj-c中的键值编码(以后简称KVC,Key-Value Coding)来存取类的属性,通过指定所要访问的属性名字符串标示符,可以使用存取器方法来获取或设置类的属性.下面的例子,借助于K ...

  6. 【深度学习】目标检测算法总结(R-CNN、Fast R-CNN、Faster R-CNN、FPN、YOLO、SSD、RetinaNet)

    目标检测是很多计算机视觉任务的基础,不论我们需要实现图像与文字的交互还是需要识别精细类别,它都提供了可靠的信息.本文对目标检测进行了整体回顾,第一部分从RCNN开始介绍基于候选区域的目标检测器,包括F ...

  7. ORACLE数据库部分面试题目

    1. 解释冷备份和热备份的不同点以及各自的优点 解答:热备份针对归档模式的数据库,在数据库仍旧处于工作状态时进行备份.而冷备份指在数据库关闭后,进行备份,适用于所有模式的数据库.热备份的优点在于当备份 ...

  8. 解决记录:win10 无法安装VS2017,visual studio installer下载进度始终为0

    问题描述:win10 下无法安装VS2017,visual studio installer下载进度始终为0,点击取消按钮后,也没有反应,visual studio installer也关闭不掉: 具 ...

  9. AngularJs 学习笔记(四)服务

    模型是指$scope上保存的包含瞬时状态数据的JavaScript对象. 服务是一个单例对象,只会被$injector实例化一次,并且是在需要的时候才会被创建,服务提供了把与特定功能相关联的方法集中在 ...

  10. 推荐个Mac OSX下的Code Editor:Atom

    首先只是当Editor用,不是整成IDE级. 先说几个大家耳熟能详的: 1.Sublime,Sublime在Mac下的安装并不完全,CLI启动需要自己ln个链接.还有一些其他原因,比如Packages ...