Demo.java:
package cn.xxx.demo; /* * 开启输入线程和输出线程,实现赋值和打印值。 同步synchronized可以保证赋值的年龄和姓名是对应的。 wait/notify可以保证赋值和输出是交替进行的。 */ public class Demo{ public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread tin = new Thread(in); Thread tout = new Thread(out); tin.start(); tout.start(); } }Resource.java(输入线程和输出线程共同操作的对象类):
package cn.xxx.demo; /* * 定义资源类,有2个成员变量 * name,sex * 同时有2个线程,对资源中的变量操作 * 1个对name,age赋值 * 2个对name,age做变量的输出打印 */ public class Resource { public String name; public String sex; public boolean flag = false; // 可以进行的操作是赋值还是输出的标志位。 }Input.java(输入线程类,实现Runnable接口,重写run方法):
package cn.xxx.demo; /* * 输入的线程,对资源对象Resource中成员变量赋值 * 一次赋值 张三,男 * 下一次赋值 lisi,nv */ public class Input implements Runnable { // 实现Runnable接口 private Resource r ; public Input(Resource r){ this.r = r; } public void run() { // 重写run方法 int i = 0 ; while(true){ synchronized(r){ // 锁对象必须是多线程的共享对象。 (同步可以保证r对象的姓名和年龄是对应的) //标记是true,等待 if(r.flag){ try{r.wait();}catch(Exception ex){} // wait()的调用者必须是锁对象 (等待、唤醒可以保证交替输入、输出) } if(i%2==0){ r.name = "张三"; r.sex = "男"; }else{ r.name = "lisi"; r.sex = "nv"; } //将对方线程唤醒,标记改为true r.flag = true; r.notify(); // 唤醒 notify()的调用者必须是锁对象 } i++; } } }Output.java(输出线程类,实现Runnable接口,重写run方法):
package cn.xxx.demo; /* * 输出线程,对资源对象Resource中成员变量,输出值 */ public class Output implements Runnable { // 实现Runnable接口 private Resource r ; public Output(Resource r){ this.r = r; } public void run() { // 重写run方法 while(true){ synchronized(r){ // 锁对象必须是多线程的共享对象。 (同步可以保证r对象的姓名和年龄是对应的) //判断标记,是false,等待 if(!r.flag){ try{r.wait();}catch(Exception ex){} // wait()的调用者必须是锁对象 (等待、唤醒可以保证交替输入、输出) } System.out.println(r.name+".."+r.sex); //标记改成false,唤醒对方线程 r.flag = false; r.notify(); // 唤醒 notify()的调用者必须是锁对象 } } } }