admin管理员组文章数量:1599541
使用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锁释放了
版权声明:本文标题:Java使用Condition唤醒指定线程 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728324610a1154273.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论