多线程之间通信

什么是多线程之间通讯?

   多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。

   画图演示

     

                              

 方法一:synchronized和wait配套使用

Object类的方法部分截图:

其中我们要用到的是wait()、notify()notifyAll()是三个方法,可以用来控制线程的状态。

这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。

  • 如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
  • 如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
  • 如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

实现:

问题描述:第一个线程写入(input)用户,另一个线程取读取(out)用户.实现读一个,写一个操作。

/**
 * 共享资源
 * @author lenovo
 *
 */
class Res{
	public String name;
	public String sex;
	public Boolean flag = false;
}

/**
 * 写入线程
 * @author lenovo
 *
 */
class InputThread extends Thread{
	public Res res;
	
	public InputThread(Res res) {
		this.res = res;
	}

	@Override
	public void run() {
		int count = 0;
		while(true) {
			synchronized (res) {
				if(res.flag) {
					try {
						//wait要和synchronized 配套使用
						//wait可以释放锁,而sleep不能释放锁
						res.wait();
					} catch (Exception e) {
						// TODO: handle exception
					}
				}
				if(count == 0) {
					res.name = "阿斗";
					res.sex = "男";
				}else {
					res.name = "老嫂子";
					res.sex = "女";
				}
				count = (count+1)%2;
				res.flag = true;
				//notify和wait一起使用,
				//唤醒另一个线程,让另一个线程从阻塞状态变为运行状态
				res.notify();
			}
		}
	}
}

/**
 * 读取线程
 * @author lenovo
 *
 */
class OutputThread extends Thread{
	public Res res;
	
	public OutputThread(Res res) {
		this.res = res;
	}
	
	@Override
	public void run() {
		while(true) {
			synchronized (res) {
				if(!res.flag) {
					try {
						res.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println(res.name + "----" +res.sex);
				res.flag = false;
				res.notify();
			}
		}
	}
	
}

/**
 * 
 * @author lenovo
 *
 */
public class ThreadDemo01 {
	
	public static void main(String[] args) {
		Res res = new Res();
		
		InputThread inputThread = new InputThread(res);
		OutputThread outputThread = new OutputThread(res);
		inputThread.start();
		outputThread.start();
		
	}
	
}

 

 方法二:Lock接口与Condition对象实现

①Lock接口的实现类ReentrantLock作用:

        ReentrantLock是一个可重入的互斥锁,ReentrantLock由最近成功获取锁,还没有释放的线程所拥有,当锁被另一个线程拥有时,调用lock的线程可以成功获取锁。如果锁已经被当前线程拥有,当前线程会立即返回

 ②Contion接口

③Condition接口的方法:

Condition condition = lock.newCondition();

await();  类似wait

signal() 类似notify

signalAll 类似notifyAll

实现:

/**
 * 共享资源
 * @author lenovo
 *
 */
class Res{
	public String name;
	public String sex;
	public Boolean flag = false;
	public Lock lock = new ReentrantLock();
	Condition condition = lock.newCondition();
}

/**
 * 写入线程
 * @author lenovo
 *
 */
class InputThread extends Thread{
	public Res res;
	
	public InputThread(Res res) {
		this.res = res;
	}

	@Override
	public void run() {
		int count = 0;
		while(true) {
			try {
				res.lock.lock();
				if(res.flag) {
					res.condition.await();
				}
				if(count == 0) {
					res.name = "阿斗";
					res.sex = "男";
				}else {
					res.name = "老嫂子";
					res.sex = "女";
				}
				count = (count+1)%2;
				res.flag = true;
				res.condition.signal();
			} catch (Exception e) {
				// TODO: handle exception
			}finally {
				res.lock.unlock();
			}
			
			
		}
	}
}

/**
 * 读取线程
 * @author lenovo
 *
 */
class OutputThread extends Thread{
	public Res res;
	
	public OutputThread(Res res) {
		this.res = res;
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				res.lock.lock();
				if(!res.flag) {
					res.condition.await();
				}
				System.out.println(res.name + "----" +res.sex);
				res.flag = false;
				res.condition.signal();
			} catch (Exception e) {
				// TODO: handle exception
			}finally {
				res.lock.unlock();
			}
		}
	}
	
}

/**
 * 
 * @author lenovo
 *
 */
public class ThreadDemo01 {
	
	public static void main(String[] args) {
		Res res = new Res();
		
		InputThread inputThread = new InputThread(res);
		OutputThread outputThread = new OutputThread(res);
		inputThread.start();
		outputThread.start();
		
	}
	
}
发布了138 篇原创文章 · 获赞 22 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/guihaiyuan123/article/details/105566406