简介

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. 【翻译】在Ext JS应用程序中使用自定义图标

    原文:Using Custom Icons in Your Ext JS App 作者:Lee BoonstraLee is a technical trainer at Sencha. She's ...

  2. Android驱动中的Kconfig文件与Makefile文件

    内核源码树的目录下都有两个文档Kconfig(2.4版本是Config.in)和Makefile.分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文 ...

  3. 让App中加入LruCache缓存,轻松解决图片过多造成的OOM

    上次有过电话面试中问到Android中的缓存策略,当时模糊不清的回答,现在好好理一下吧. Android中一般情况下采取的缓存策略是使用二级缓存,即内存缓存+硬盘缓存->LruCache+Dis ...

  4. JQuery UI - resizable

     ·概述 resizable插件可以让选中的元素具有改变尺寸的功能. 官方示例地址:http://jqueryui.com/demos/resizable/ 所有的事件回调函数都有两个参数:eve ...

  5. Android全局异常处理 实现自己定义做强制退出和carsh日志抓取

    在做android项目开发时,大家都知道都会遇到程序报错或者Anr异常,会弹出来一个强制退出的弹出框,对于开发人员是好事,但是对于用户体验和 UI实在毫无违和感,别说用户接受不了,就连我们自己本身可能 ...

  6. WinCE系统声音定制

    作者:ARM-WinCE 2010的第一篇Blog,介绍一下WinCE系统声音的定制.说白了,就是设置注册表.WinCE系统启动的开机音乐,点击触摸屏以及键盘输入的按键音,还有系统运行过程中的各种声音 ...

  7. break和continue的简单介绍

    1.break break 用于完全结束一个循环,跳出循环体!不管是哪种循环,如果在程序中遇到Break,系统将完全结束该循环,开始执行循环之后的代码: public class TestBreak ...

  8. 恶补web之八:jQuery(2)

    jquery中非常重要的部分,就是操作dom的能力: text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容(包括html标记) val() - 设置或返回表单字段 ...

  9. ELF 文件 动态链接 - 地址无关代码(GOT)

    Linux 系统中,ELF动态链接文件被称为 动态共享对象(DSO,Dynamic Shared Object),简称共享对象 文件拓展名为".so" 动态链接下 一个程序可以被分 ...

  10. Java的运行原理

    在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由 ...