Java使用Condition唤醒指定线程
2017-05-20 17:36
465 查看
使用ReentrantLock实现同步
首先创建一个功能类,用于实现线程的功能
创建的四个线程,两个运行methodA,两个运行methodB
运行结果:
Thread-0 进入methodA 并得到锁
Thread-0 离开methodA 并释放锁
Thread-1 进入methodA 并得到锁
Thread-1 离开methodA 并释放锁
Thread-2 进入methodB 并得到锁
Thread-2 离开methodB 并释放锁
Thread-3 进入methodB 并得到锁
Thread-3 离开methodB 并释放锁
目前来看,lock和unlock之间是被锁定的,这一点和关键字synchronized作用相同
使用Condition唤醒指定线程
synchronized关键字与wait()和notify()/notifyAll()结合能够实现等待通知模型,但是却面临一个问题,就是,被wait()唤醒的线程是随机的,而notifyAll()唤醒的又是所有的,不能唤醒指定的线程。
ReentrantLock借助于Condition就可以实现唤醒指定线程,这样在线程调度上更加灵活。
四个线程类
运行结果:
执行 await1 方法
执行 await2 方法
执行signal1方法 //threadB只唤醒了由condition等待的线程
通知了await1
await1 锁释放了
执行signal2方法
通知了await2
await2锁释放了
首先创建一个功能类,用于实现线程的功能
public class MyService { private Lock lock = new ReentrantLock(); public void methodA() { try { lock.lock(); //加锁,作用相当于synchronized System.out.println(Thread.currentThread().getName()+" 进入methodA 并得到锁"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(Thread.currentThread().getName()+" 离开methodA 并释放锁"); lock.unlock(); //释放锁 } } public void methodB() { try { lock.lock(); System.out.println(Thread.currentThread().getName()+" 进入methodB 并得到锁"); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(Thread.currentThread().getName()+" 离开methodB 并释放锁"); lock.unlock(); } } }
创建的四个线程,两个运行methodA,两个运行methodB
public static void main(String[] args) { final MyService service = new MyService(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub service.methodA(); } }).start(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub service.methodA(); } }).start(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub service.methodB(); } }).start(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub service.methodB(); } }).start(); }
运行结果:
Thread-0 进入methodA 并得到锁
Thread-0 离开methodA 并释放锁
Thread-1 进入methodA 并得到锁
Thread-1 离开methodA 并释放锁
Thread-2 进入methodB 并得到锁
Thread-2 离开methodB 并释放锁
Thread-3 进入methodB 并得到锁
Thread-3 离开methodB 并释放锁
目前来看,lock和unlock之间是被锁定的,这一点和关键字synchronized作用相同
使用Condition唤醒指定线程
synchronized关键字与wait()和notify()/notifyAll()结合能够实现等待通知模型,但是却面临一个问题,就是,被wait()唤醒的线程是随机的,而notifyAll()唤醒的又是所有的,不能唤醒指定的线程。
ReentrantLock借助于Condition就可以实现唤醒指定线程,这样在线程调度上更加灵活。
public class MyService { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); private Condition condition2 = lock.newCondition(); public void await1() { try { lock.lock(); System.out.println("执行 await1 方法"); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); System.out.println("await1 锁释放了"); } } public void await2() { try { lock.lock(); System.out.println("执行 await2 方法"); condition2.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); System.out.println("await2锁释放了"); } } public void signal1() { try { lock.lock(); System.out.println("执行signal1方法"); condition.signal(); System.out.println("通知了await1 "); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void signal2() { try { lock.lock(); System.out.println("执行signal2方法"); condition2.signal(); System.out.println("通知了await2 "); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
四个线程类
public class ThreadA extends Thread{ private MyService service; public ThreadA(MyService service) { this.service = service; } public void run() { service.await1(); } }
public class ThreadAA extends Thread{ private MyService service; public ThreadAA(MyService service) { this.service = service; } public void run() { service.await2(); } }ThreadB用于唤醒由condition等待的线程
public class ThreadB extends Thread{ private MyService service; public ThreadB(MyService service) { this.service = service; } public void run() { service.signal1(); } }threadBB用于唤醒由condition2等待的线程
public class ThreadBB extends Thread { private MyService service; public ThreadBB(MyService service) { this.service = service; } public void run() { service.signal2(); } }
public static void main(String[] args) { MyService service = new MyService(); ThreadA threadA = new ThreadA(service); ThreadAA threadAA = new ThreadAA(service); ThreadB threadB = new ThreadB(service); ThreadBB threadBB = new ThreadBB(service); try { threadA.start(); threadAA.start(); Thread.sleep(300); threadB.start(); ThreadA.sleep(3000); threadBB.start(); } catch (InterruptedException e) { e.printStackTrace(); } }
运行结果:
执行 await1 方法
执行 await2 方法
执行signal1方法 //threadB只唤醒了由condition等待的线程
通知了await1
await1 锁释放了
执行signal2方法
通知了await2
await2锁释放了
相关文章推荐
- java多线程学习之Condition,实现唤醒指定的部分线程
- java学习——如何实现线程之间的通信 ,Condition 的使用
- Java 多线程 (PART XIX) 使用Condition实现线程的顺序执行
- java线程通讯——使用Lock和Condition代替synchronized 和 wait, notify notifyAll()
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
- Java并发——使用Condition线程间通信
- Java多线程(3):使用Condition中的await、signal进行线程间协作
- java线程通讯——使用Lock和Condition代替synchronized 和 wait, notify notifyAll()
- java线程 使用显示的lock 和condition
- 12-使用java5条件阻塞condition实现线程间通信-实现线程间通信方式(2)
- java中使用ReentrantLock锁中的Condition实现三个线程之间通信,交替输出信息
- java线程通讯——使用Lock和Condition代替synchronized 和 wait, notify notifyAll()
- JAVA线程锁lock下Condition高级使用-多个Condition的整合使用
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
- java 中wait和notify 线程等待和线程唤醒的使用方式 需要借助synchronized
- JAVA5多线程---Condition使用---线程通信
- 在Java的Condition接口【唤醒全部线程】
- java线程通讯——使用Lock和Condition代替synchronized 和 wait, notify notifyAll()
- JAVA5多线程---Condition使用---线程通信 --wait及notify方法
- python里使用Condition对象来唤醒指定数量的协程