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()的调用者必须是锁对象
}
}
}
}