Java使用Condition唤醒指定线程

使用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唤醒指定线程)