🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 线程之间的通信 描述:存在两个线程,一个线程负责写入信息,另一个线程负责打印信息。 model类Student name sex (私有类) 线程:Input类,Output类。 启动两个线程分别执行打印和写入操作. ~~~ public class InputOutputDemo{ public static void main(String args[]){ Student stu = new Student(); Input in = new Input(stu); Output out = new Output(stu); Thread t1 = new Thread(in); //存入学生信息的线程 Thread t2 = new Thread(out); //打印学生信息的线程 t1.start(); t2.start(); } } class Input implements Runnable{ private Student stu; boolean flag = false; public Input(Student stu){ this.stu = stu; } public void run(){//这个线程的run方法负责将姓名和性别存入 /*在这里定义两个学生切换着存入学生的信息 */ while(true){ if(flag){ stu.name = "xy"; stu.sex = "woman"; flag = false; }else{ stu.name = "李志磊"; stu.sex = "男男男男男男"; flag = true; } } } } class Output implements Runnable{ private Student stu; public Output(Student stu){ //保证传入对象唯一性 this.stu = stu; } public void run(){ while(true) System.out.println(stu.name+"..."+stu.sex); } } class Student{ String name; String sex; } ~~~ 打印信息: ~~~ xy...woman xy...woman xy...男男男男男男 xy...woman 李志磊...woman 李志磊...男男男男男男 李志磊...男男男男男男 李志磊...男男男男男男 ~~~ 当线程执行之后,会出现线程间数据问题。(这里需要使用同步的方法来修改代码) 同步的前提: 1、至少有两个线程,在程序中运行 2、同步时使用同一个锁对象。 ~~~ public class InputOutputDemo{ public static void main(String args[]){ Student stu = new Student(); Input in = new Input(stu); Output out = new Output(stu); Thread t1 = new Thread(in); //存入学生信息的线程 Thread t2 = new Thread(out); //打印学生信息的线程 t1.start(); t2.start(); } } class Input implements Runnable{ private Student stu; boolean flag = false; public Input(Student stu){ this.stu = stu; } public void run(){//这个线程的run方法负责将姓名和性别存入 /*在这里定义两个学生切换着存入学生的信息 */ while(true){ synchronized(stu){ if(flag){ stu.name = "xy"; stu.sex = "woman"; flag = false; }else{ stu.name = "李志磊"; stu.sex = "男男男男男男"; flag = true; } } } } } class Output implements Runnable{ private Student stu; public Output(Student stu){ //保证传入对象唯一性 this.stu = stu; } public void run(){ while(true) synchronized(stu){ System.out.println(stu.name+"..."+stu.sex); } } } class Student{ String name; String sex; } ~~~ ### 唤醒等待机制(重要) java Object类中存在以下方法: wait(): notify(); notifyAll(); 特点:都使用在同步当中,因为要对持有锁(监视器)的对象操作。 所以要在同步中使用,因为同步中才有锁。 描述:要求input类读入一个信息,紧接着output就打印出这条信息。 解决思路: 我们需要将这个类添加一个标识flag。 flag==flase时:表示input没有信息 input开始读入信息,将flag设置为true,并将output唤醒 flag==true时:表示input有信息。 ouput开始打印信息,将flag设置为false,并唤醒input ~~~ public class InputOutputDemo1{ public static void main(String args[]){ Student stu = new Student(); Input in = new Input(stu); Output out = new Output(stu); Thread t1 = new Thread(in); //存入学生信息的线程 Thread t2 = new Thread(out); //打印学生信息的线程 t1.start(); t2.start(); } } class Input implements Runnable{ private Student stu; boolean flag = false; int x=0; public Input(Student stu){ this.stu = stu; } public void run(){//这个线程的run方法负责将姓名和性别存入 /*在这里定义两个学生切换着存入学生的信息 */ while(true){ if(flag){ stu.set("xy","woman"); flag = false; }else{ stu.set("李志磊","男男男男男"); flag = true; } } } } class Output implements Runnable{ private Student stu; public Output(Student stu){ //保证传入对象唯一性 this.stu = stu; } public void run(){ while(true){ stu.out(); } } } class Student{ private String name; private String sex; private boolean flag; //设置标志,默认为false public synchronized void set(String name,String sex){ if(flag) try{this.wait();}catch(Exception e){}; this.name = name; this.sex = sex; flag = true; this.notify(); } public synchronized void out(){ if(!flag){ try{this.wait();}catch(Exception e){}; }else{ System.out.println(name+"-----"+sex); flag = false; this.notify(); } } } ~~~