日期:2014-05-20  浏览次数:20799 次

多线程安全问题
本帖最后由 xuezhezhao 于 2012-11-24 14:30:22 编辑

/*多线程_等待唤醒机制*/

/**
*需求:创建两个线程,一个进行存储信息,一个进行打印信息。
*目的:程序输入一个"mike man"打印一个"mike man"
*    输入一个"莉莉 女女女女女"打印一个"莉莉 女女女女女"
*步骤:创建一个共享资源类RescourceWaitNotifyDemo
* 创建输入线程类InputWaitNotifyDemo
* 创建打印线程类OutputWaitNotifyDemo
* 由主函数创建线程,并执行。
*问题:
* 为什么会有线程安全问题?
* 怎么解决?
*/

/*线程共享资源类,信息类*/
class ResourceWaitNotifyDemo //
{
private String name;
private String sex;
private boolean flag=false;


public synchronized void setInfo(String name,String sex)//信息输入函数
{
if(flag)
/*如果flag值为false,则共享资源中没有信息,进行赋值
  如果为true,则共享资源中有信息没有打印,不进行赋值,进行wait操作
*/
{
try
{
this.wait();
}
catch (Exception e)
{
}
}
else
{
this.name = name;
this.sex = sex;
}
flag=true;  //改变开关,让输入程序不能再次进行赋值,同时可以让打印程序启动
this.notify();//唤醒输出线程
}

public synchronized void OutInfo()//信息输出函数
{
if (!flag)//如果flag值为ture,则共享资源中有信息,进行打印,否则等待
{
try
{
this.wait();
}
catch (Exception e)
{
}
}
else
{
System.out.println(name+"......"+sex);
}
flag=false; //改变开关,让输入程序可以进行赋值,同时让自己不能在打印
this.notify();//唤醒输入线程
}
}

/*输入线程*/
class InputWaitNotifyDemo implements Runnable
{
private ResourceWaitNotifyDemo r; //创建共享类引用

InputWaitNotifyDemo(ResourceWaitNotifyDemo r)
{
this.r = r; //接收共享类对象
}

public void run()
{
int x=0;
while(true)
{
if (x==0)
{
r.setInfo("mike","man");
}
else
{
r.setInfo("莉莉","女女女女女");
}
x=(x+1)%2;
}
}

}

/*输出线程*/
class OutputWaitNotifyDemo implements Runnable
{
private ResourceWaitNotifyDemo r;

OutputWaitNotifyDemo(ResourceWaitNotifyDemo r)
{
this.r = r; //和输入线程操作同一个共享类对象
}

public void run()
{
while (true)
{
r.OutInfo();
}
}
}

/*主函数*/
class ThreadWaitNotifyTest
{
public static void main(String[] args)
{
ResourceWaitNotifyDemo res = new ResourceWaitNotifyDemo();
/*
InputWaitNotifyDemo i = new InputWaitNotifyDemo(res);
OutputWaitNotifyDemo o = new OutputWaitNotifyDemo(res);

Thread t1 = new Thread(i);
Thread t2 = new Thread(o);

t1.start();
t2.start();
*/
new Thread(new InputWaitNotifyDemo(res)).start(); //创建输入线程
new Thread(new OutputWaitNotifyDemo(res)).start(); //创建打印线程
}
}


------最佳解决方案--------------------
引用:
不是,我这个线程是非安全的,我预想的结果是,程序自动输入一个,然后就打印一个,可是我这个程序的线程是非安全的,输入一片,输出一片,完全不是预想的那样。试问,怎么解决这个问题?

楼主的问题是 setInfor()和OutInfor().
楼主的代码:
        if(flag)
        /*如果flag值为false,则共享资源中没有信息,进行赋值
          如果为true,则共享资源中有信息没有打印,不进行赋值,进行wait操作