您的位置:首页 > 编程语言 > Java开发

Java使用Condition唤醒指定线程

2017-05-20 17:36 465 查看
使用ReentrantLock实现同步

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

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锁释放了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐