线程间通信Demo

1、实验要求

        使用四个线程AA,BB,CC,DD,AA,CC一个对象进行加1操作,BB,DD对一个对象进行减1操作。

2、实验步骤

        (1)创建资源类

          以number为依据做加减操作判断,分别在资源类中添加加减方法使用ReentrantLock对象进行上锁和解锁。 

        其中:

                lock.lock(); // 代表上锁

                lock.unlock(); // 代表解锁

                condition.await(); // 类似于Object.wait(); 使当前线程等待,并释放锁。

                condition.signalAll(); // 类似于Object.notifyAll(); // 唤醒所有等待中的锁

         PS:

                wait();操作必须要放在while循环中判断,如果使用if来做判断则会发生虚假唤醒状况。

//创建资源类
class Share {
	// 初始值
	private int number = 0;

	// 可重入锁
	private final Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();

	// 加1
	public void incr() throws InterruptedException {
		// 上锁
		lock.lock();
		try {

			// 判断
			while (number != 0) { // 如果不为0就等待
				condition.await();
			}
			number++;
			System.out.println(Thread.currentThread().getName() + "::" + number);
			// 通知
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}

	// 减1
	public void decr() throws InterruptedException {
		// 上锁
		lock.lock();
		try {

			// 判断
			while (number != 1) { // 如果不为1就等待
				condition.await();
			}
			number--;
			System.out.println(Thread.currentThread().getName() + "::" + number);
			// 通知
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}
}

        (2)测试类

        此处使用lambda表达式的方式创建线程并启动。

public class ThreadDemo2 {
	
	public static void main(String[] args) {
		Share share = new Share();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.incr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "AA").start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.decr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "BB").start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.incr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "CC").start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.decr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "DD").start();
		
	}

}

        (3)测试

线程间通信Demo

 3、整体代码

package lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo2 {
	
	public static void main(String[] args) {
		Share share = new Share();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.incr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "AA").start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.decr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "BB").start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.incr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "CC").start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					share.decr();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "DD").start();
		
	}

}

//创建资源类
class Share {
	// 初始值
	private int number = 0;

	// 可重入锁
	private final Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();

	// 加1
	public void incr() throws InterruptedException {
		// 上锁
		lock.lock();
		try {

			// 判断
			while (number != 0) { // 如果不为0就等待
				condition.await();
			}
			number++;
			System.out.println(Thread.currentThread().getName() + "::" + number);
			// 通知
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}

	// 减1
	public void decr() throws InterruptedException {
		// 上锁
		lock.lock();
		try {

			// 判断
			while (number != 1) { // 如果不为1就等待
				condition.await();
			}
			number--;
			System.out.println(Thread.currentThread().getName() + "::" + number);
			// 通知
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}
}
上一篇:Netty入门教程——认识Netty


下一篇:【Java】finally用法