简介

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学习笔记(三)Java2D组件

    一  概述 Java2D的一切都基于java.awt包中的Graphics2D类,它是Graphics的子类. 为了绘制图形,需要使用面板作为画布,例如使用JPanel作为画布,面板有一个paintC ...

  2. Erlang Rebar 使用指南之二:制作发布版本

    Erlang Rebar 使用指南之二:制作发布版本 全文目录: https://github.com/rebar/rebar/wiki 本章位置: https://github.com/rebar/ ...

  3. Android性能优化典例(二)

    1.使用 Maven 依赖方案代替使用导入jar包方案 如果项目中需要用到第三方jar包,常用的做法是去网上下载后然后放入libs文件夹,再添加到项目依赖,不过,在Android Studio已经不推 ...

  4. Linux常用命令(第二版) --文件管理命令

    文件管理命令 并不建议:照着像命令大全这类的书来学! 常用命令大约有200个. 文件命名规则: a)除了'/'之外所有字符都合法! b)这些字符最好不用 1.空格符,制表符,退格符 2.连接符 3.特 ...

  5. Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片

    Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一 ...

  6. Android模拟器启动不了解决办法

    问题描述:Windows2008中的MyEclipse项目在Windows2003中运行时无法启动模拟器. 解决要点:启动模拟器管理工具,在启动中设置属性中不勾选默认尺寸显示. 系统错误如下: [20 ...

  7. iOS 百度地图计算两个点时间的距离

    最近在解项目bug,更新地位城市的时候有个错误,后来想在位置改变多少距离之后,再取更新位置,这个功能去年做过.但是又忘记了! 所以还是记录一下吧. 百度地图提供了一个方法: BMKMapPointFo ...

  8. Oracle技术面试问题

    这也许是你一直期待的文章,在关注这部分技术问题的同时,请务必阅读有关面试中有关个人的问题和解答.这里的回答并不是十分全面,这些问题可以通过多个 角度来进行解释,也许你不必在面试过程中给出完全详尽的答案 ...

  9. 并发编程(四):atomic

    本篇博客我们主要讲述J.U.C包下的atomic包,在上篇博客"并发模拟"的最后,我们模拟高并发的情形时出现了线程安全问题,怎么解决呢?其实解决的办法有很多中,如直接在add()方 ...

  10. eclipse乱码

    eclipse乱码:Windows >general >Workspace UTF-8Windows >general >Editors >Text Editors &g ...