class Resource{
String name;
String sex;
}
//输入
class Input implements Runnable{
//Resource r = new Resource();操作的应该是同一个资源,所以这么做不合适
//应该在外面把对象建立好,分别传入给输入和输出,能接受参数的函数只有两种,一种是普通函数,一种是构造函数
//那我们为什么不能,对象一初始化,就有这些资源呢,就像线程一样,线程对象一创建,就要有线程任务。
Resource r;
//Object obj = new Object();
Input(Resource r){
this.r = r;
}
public void run(){
while(true){//实现两个,达到间隔切换,好像在输入很多人的名字,既然设计到切换,应该是两种状态,由if语句控制
synchronized(r){
/*当碰到线程安全的问题的时候,我们会想到使用同步,但是发现同步的时候,并不能解决问题,说明了什么,
应该考虑一下,同步的使用前提。并且明确,解决问题的方案是:多个线程,在同一个锁当中。
当前语句只是输入线程被同步了,那还有输出线程呢?
就是说,我在输入线程执行的时候,你不能够去取这些数据。所以我们需要再同步输出线程*/
if(x == 0){
r.name = "mike";
r.sex = "nan";
)
else{
r.name = "丽丽";
r.sex = "女";
}
}
x = (x + 1)%2; //为了实现x的变化
}
}
}
//输出
class Output implements Runnable{
//Resource r = new Resource();
Resource r;
//Object obj = new Object();
Output(Resource r){
this.r = r;
}
public void run(){
while(true){
synchronized(r){/*这时候,即使在对输出线程作了同步,仍然会出现线程的安全问题(妖),因为这两个同步代码块
使用的是不同的锁。当然也不能使用this作为锁,因为这是两个不同的类,是两个不同的对象。那可
不可以用静态锁呢?
Input.class、Output.class,都是可以的,Resource.class也是可以的,
但杀鸡何必用牛刀呢。
我们注意到,整个过程中,资源r是唯一的,所以锁可以用r,并且同步代码块需要放在while循环里面
输入线程,拿到执行权的时候,不会只执行一次,等执行到一定次数后,执行权到了输出线程,从最后一
次开始输出,所以结果会出现一片一片的输出。
}
*/
System.out.println(r.name+"..."+r.sex);
}
}
}
}
class ResourceDemo{
public static void main(String [] args){
//创建资源
Resource r = new Resource();//这句代码产生的原因就是,不同的任务需要产生相同的资源
//创建任务
Input in = new Input(r);
Output out = new Output(r);
//资源有了,任务有了,应该有路径了
//创建线程
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
//开启线程
t1.start();
t2.start();
}
}
//执行结果,会出现mike ... 女 的现象。
/*
分析出现"妖"的原因:
已经输入一次的情况下,如mike man,在准备再输入第二次数据的时候,刚输入了丽丽,输出线程就执行了,
所以出现了丽丽 man的情况。
解决方案:synchronized,将if语句里面的内容加入同步代码块中
*/