Java 多线程(一)线程间的通信

本文通过实例详细介绍了线程间通信的基本概念与实现方法,包括如何利用同步机制防止数据竞争,以及如何运用唤醒等待机制协调多线程间的操作顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.线程间通讯的理解

线程间通讯:

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

2.线程间通信的示例代码

   描述:存在两个线程,一个线程负责写入信息,另一个线程负责打印信息。
   model类Student   属性name sex (私有类)
   线程:Input类,Output类。

   启动两个线程分别执行打印和写入操作。

   
   
   
   
/**
 * 
 */
package threadCommnication;

/**
 * <p>Title: InputOutputDemo</p>
 * <p>Description: </p>
 * <p>Company: </p>
 * @author 夏 杰
 * @date 2015年12月12日 下午8:40:53
 * @vesion 1.0
*/
public class InputOutputDemo {


	public static void main(String[] args) {
		Student student = new Student();
		Input input = new Input(student);
        Output output = new Output(student);
        
        //存入学生信息的线程
        new Thread(input).start();
        //打印学生信息的线程  
        new Thread(output).start();
        
	}

}
/**
 * 
 */
package threadCommnication;


public class Input implements Runnable{
    private Student student;
    boolean flag = false; 
    
    //保证传入对象唯一性  
	public Input(Student student) {
		this.student = student;
	}

	@Override
	public void run() {
		 /*在这里定义两个学生切换着存入学生的信息 
		    */  
		    while(true){  
		        if(flag){  
		        	student.name = "xy";  
		        	student.sex = "woman";  
		            flag = false;  
		        }else{  
		        	student.name = "乔布斯";  
		        	student.sex = "男男男男男男";  
		            flag = true;  
		        }  
		    }  
		
	}
	
}
/**
 * 
 */
package threadCommnication;


public class Output  implements Runnable{
	private Student stu;
	  public Output(Student stu){  //保证传入对象唯一性  
		    this.stu = stu;  
		  }  
	@Override
	public void run() {
		while(true){
			 System.out.println(stu.name+"..."+stu.sex);  
		}
		
	}

}
public class Student {
	  String name;  
	  String sex;
	
}



当线程执行之后,会出现线程间数据问题。(这里需要使用同步的方法来修改代码)

注意:最好不要在整个方法上加锁,最好在代码块上,因为一个方法上不可能全部都是互斥的,这样执行效率会比较低

这里开始尝试给线程加锁



但是虽然加了同步锁,但是由于加的锁并不是同一个把锁,所以不能够限制对象同步,还会出现不同步的情况

这是就需要检查同步的前提条件了:
同步的前提:
1、至少有两个线程,在程序中运行
2、同步时使用同一个锁对象

   
注意:最好不要在整个方法上加锁,最好在代码块上,因为一个方法上不可能全部都是互斥的,这样执行效率会比较低

改成这样就行了,同用student这把锁



3.多线程中的唤醒等待机制(重要)

java Object类中存在以下方法:
wait():
notify();
notifyAll();

特点:都使用在同步当中,因为要对持有锁(监视器)的对象操作。
所以要在同步中使用,因为同步中才有锁。

 描述:要求input类读入一个信息,紧接着output就打印出这条信息。
   解决思路:
      我们需要将这个类添加一个标识flag。
       flag==flase时:表示input没有信息
         input开始读入信息,将flag设置为true,并将output唤醒
       flag==true时:表示input有信息。
         ouput开始打印信息,将flag设置为false,并唤醒input

[java]  view plain copy
  1. public class InputOutputDemo1{  
  2.   public static void main(String args[]){  
  3.       Student stu = new Student();  
  4.       Input in = new Input(stu);  
  5.       Output out = new Output(stu);  
  6.       Thread t1 = new Thread(in);  //存入学生信息的线程  
  7.       Thread t2 = new Thread(out); //打印学生信息的线程  
  8.       t1.start();  
  9.       t2.start();  
  10.   }  
  11. }  
  12. class Input implements Runnable{  
  13.   private Student stu;  
  14.   boolean flag = false;  
  15.   int x=0;  
  16.   public Input(Student stu){  
  17.     this.stu = stu;  
  18.   }  
  19.   public void run(){//这个线程的run方法负责将姓名和性别存入  
  20.     /*在这里定义两个学生切换着存入学生的信息 
  21.     */  
  22.     while(true){  
  23.           if(flag){  
  24.             stu.set("xy","woman");  
  25.             flag = false;  
  26.           }else{  
  27.             stu.set("李志磊","男男男男男");  
  28.             flag = true;  
  29.           }  
  30.     }  
  31.   }  
  32. }  
  33. class Output implements Runnable{  
  34.   private Student stu;  
  35.   public Output(Student stu){  //保证传入对象唯一性  
  36.     this.stu = stu;  
  37.   }  
  38.   public void run(){  
  39.     while(true){  
  40.           stu.out();  
  41.     }  
  42.   }  
  43. }  
  44. class Student{  
  45.   private String name;  
  46.   private String sex;  
  47.   private boolean flag;  //设置标志,默认为false  
  48.   
  49.   public synchronized void set(String name,String sex){  
  50.     if(flag)  
  51.         try{this.wait();}catch(Exception e){};  
  52.     this.name = name;  
  53.     this.sex = sex;  
  54.     flag = true;  
  55.     this.notify();  
  56.   }  
  57.   public synchronized void out(){  
  58.     if(!flag){  
  59.         try{this.wait();}catch(Exception e){};  
  60.     }else{  
  61.       System.out.println(name+"-----"+sex);  
  62.       flag = false;  
  63.       this.notify();  
  64.     }  
  65.   }  
  66. }  




   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值