多线程之间实现通讯

多线程之间如何实现通讯

什么是多线程之间通讯?

多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。
画图如下:
在这里插入图片描述
我这里有个例子:就是弄两个线程,一个进行写,一个进行读,写的话,如果是偶数,就是java,男。如果是奇数,就是php 女,。
代码如下:

package com.newDemo.controller.test;

//共享资源
class res{
 public String userSex;
 public String userName;
}
//生产者线程
class inputThread extends Thread{
 res res;
 public inputThread(res res){
 	this.res = res;
 }
 
 public void run(){
 	 int count=0;
 	 while(true){
 		 if(count==0){
 			 res.userName="java";
 			 res.userSex="男";
 		 }else{
 			 res.userName="php";
 			 res.userSex="女";
 		 }
 		 count = (count + 1) % 2;
 	 }
 	
 }
}
//消费者线程
class outThread extends Thread{
 res res;
 
 public outThread(res res){
 	this.res = res;
 }
 
 public void run(){
 	while(true){
 		System.out.println(res.userName + "--" + res.userSex);
 	}
 }
}


public class threadDemo16 {
 public static void main(String[] args) {
 	res res = new res();
 	inputThread intThrad = new inputThread(res);
 	outThread outThread = new outThread(res);
 	intThrad.start();
 	outThread.start();
 }

}

结果如下:
在这里插入图片描述
发现结果乱了,出现了线程安全问题,我第一时间想到了synchronized同步代码块,两个线程用同一把锁,所以改进一下:


package com.newDemo.controller.test;

//共享资源
class res{
	public String userSex;
	public String userName;
}
//生产者线程
class inputThread extends Thread{
	res res;
	public inputThread(res res){
		this.res = res;
	}
	
	public void run(){
		 int count=0;
		 while(true){
			synchronized (res) {
				if (count == 0) {
					res.userName = "java";
					res.userSex = "男";
				} else {
					res.userName = "php";
					res.userSex = "女";
				}
				count = (count + 1) % 2;
			}
		}
		
	}
}
//消费者线程
class outThread extends Thread{
	res res;
	
	public outThread(res res){
		this.res = res;
	}
	
	public void run(){
		while (true) {
			synchronized (res) {
				System.out.println(res.userName + "--" + res.userSex);
			}
		}
	}
}


public class threadDemo16 {
	public static void main(String[] args) {
		res res = new res();
		inputThread intThrad = new inputThread(res);
		outThread outThread = new outThread(res);
		intThrad.start();
		outThread.start();
	}

}

就是给两个线程都加了同步代码块,锁都是res。结果如下;
在这里插入图片描述
发现了问题:现在是数据同步保证一致了,安全保证了,但是有重复消费的情况
解决方案如下:
生产者线程生产一个,消费者线程里面消费
生产者线程么有生产,消费者线程不能进行读
消费者线程么有消费完,生产者线程不能生产

问题来了,那么咋样让两个线程一个等另一个呢,多线程里面有wait()和notify()

wait:让当前线程从运行状态变为休眠状态,并且会释放锁的资源给苏醒的线程
notify:让当前线程从休眠状态变为运行状态,唤醒线程
但是这两个使用也有条件:
必须在线程同步中才能使用,而且必须要是同一把锁的资源
所以代码如下:

package com.newDemo.controller.test;

//共享资源
class res{
	public String userSex;
	public String userName;
	//线程通讯标识 (false  生产者线程写,消费者线程等待)(true 消费者线程读,生产者线程等待)
	public boolean flag = false;  
}
//生产者线程
class inputThread extends Thread{
	res res;
	public inputThread(res res){
		this.res = res;
	}
	
	public void run(){
		 int count=0;
		 while(true){
			synchronized (res) {
				if(res.flag){
					try {
						res.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				if (count == 0) {
					res.userName = "java";
					res.userSex = "男";
				} else {
					res.userName = "php";
					res.userSex = "女";
				}
				count = (count + 1) % 2;
				res.flag=true;
				res.notify();
			}
		}
		
	}
}
//消费者线程
class outThread extends Thread{
	res res;
	
	public outThread(res res){
		this.res = res;
	}
	
	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.userName + "--" + res.userSex);
				res.flag=false;
				res.notify();
			}
		}
	}
}


public class threadDemo16 {
	public static void main(String[] args) {
		res res = new res();
		inputThread intThrad = new inputThread(res);
		outThread outThread = new outThread(res);
		intThrad.start();
		outThread.start();
	}

}

结果如下:
在这里插入图片描述
这样就可以解决了多线程之间通讯的问题

总结

解决多线程之间通讯的问题,使用synchronized同步代码块, wait(); notify(); 三个配合使用。就可以解决。必须在线程同步中才能使用,而且必须要是同一把锁的资源

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值