Java使用Condition唤醒指定线程

来源:互联网 发布:机器人运动仿真软件 编辑:程序博客网 时间:2024/05/16 11:46

使用ReentrantLock实现同步

首先创建一个功能类,用于实现线程的功能


public class MyService {private Lock lock = new ReentrantLock();public void methodA() {try {lock.lock();  //加锁,作用相当于synchronizedSystem.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() {@Overridepublic void run() {// TODO Auto-generated method stubservice.methodA();}}).start();new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubservice.methodA();}}).start();new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubservice.methodB();}}).start();new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubservice.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锁释放了


原创粉丝点击