20150522
JDK1.5多线程同步技术,Lock操作:多个写线程和多个读线程同时操作的线程安全问题。
例子:两个生产者和两个消费者例子。
生产线程生产商品
消费者消费生产的商品
生产一个,消费一个
/*
一个生产者和一个消费者例子
生产者生产产品,然后消费者消费产品,
要求,生产一个消费一个
*/
classpcDemo
{
public static void main(String[] args)
{
Res r = new Res();
Pro pro = new Pro(r);
Conn con = new Conn(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
t1.start();
t2.start();
}
}
class Res
{
private String name;
private int count = 1;
private boolean pFlag = false;//标记
public synchronized void set(String name)
{
//生产产品
while(pFlag)
{
try
{
this.wait();
}
catch(Exception e){
}
}
this.name = name +"......" + count++;
System.out.println(Thread.currentThread().getName()+ "..." + "生产者" +this.name );
pFlag = true;
this.notify();
}
public synchronized void out()
{
if(!pFlag)
{
try
{
this.wait();
}
catch(Exception e)
{
}
}
System.out.println(Thread.currentThread().getName()+ ".........." + "消费了" +this.name );
pFlag = false;
this.notify();
}
}
class Proimplements Runnable
{
private Res r;
Pro(Res r)
{
this.r = r;
}
public void run()
{
int x = 100;
while(--x > 0)
{
r.set("+冰激凌+");
}
}
}
classConn implements Runnable
{
private Res res;
Conn(Res res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
多个生产者和多个消费者,就会出现错乱。
主函数变化如下,其他无变化:
classpcDemo
{
public static void main(String[] args)
{
Res r = new Res();
Pro pro = new Pro(r);
Conn con = new Conn(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
一:出现不协调
现在有多个生产者和多个消费者。
就会出现
生产两个而只消费一个,
生产一个,消费两次
等错误现象。
Thread-0...生产者+冰激凌+......113
Thread-3..........消费了+冰激凌+......113
Thread-2..........消费了+冰激凌+......113
二:线程都wait();
if(!pFlag)改成 while(!pFlag)
if循环判断一次,但是while循环每次都判断。所以就不会出现以上问题。
可以解决。以上现象:
但是会出现线程卡死:
Thread-3..........消费了+冰激凌+......2
Thread-0...生产者+冰激凌+......3
线程不动了。。
三:解决线程卡死
把 this.notify();
修改成 this.notifyAll();唤醒所有线程。
所有问题解决:
总结:
1、 while循环+wait() + notifyAll()配合使用,所有的线程才能正常安全的运行。
最后代码如下:
class pcDemo
{
publicstatic void main(String[] args)
{
Resr = new Res();
Propro = new Pro(r);
Conncon = new Conn(r);
Threadt1 = new Thread(pro);
Threadt2 = new Thread(pro);
Threadt3 = new Thread(con);
Threadt4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
多个生产者和多个消费者例子
生产者生产产品,然后消费者消费产品,
要求,生产一个消费一个。
*/
class Res
{
privateString name;
privateint count = 1;
privateboolean pFlag = false;//标记
publicsynchronized void set(String name)
{
//生产产品
while(pFlag)
{
try
{
this.wait();
}
catch(Exceptione){
}
}
this.name= name + "......" + count++;
System.out.println(Thread.currentThread().getName()+ "..." + "生产者" +this.name );
pFlag= true;
this.notifyAll();
}
publicsynchronized void out()
{
while(!pFlag)
{
try
{
this.wait();
}
catch(Exceptione)
{
}
}
System.out.println(Thread.currentThread().getName()+ ".........." + "消费了" +this.name );
pFlag= false;
this.notifyAll();
}
}
class Pro implements Runnable
{
privateRes r;
Pro(Resr)
{
this.r= r;
}
publicvoid run()
{
intx = 100;
while(--x> 0)
{
r.set("+冰激凌+");
}
}
}
class Conn implements Runnable
{
privateRes res;
Conn(Resres)
{
this.res= res;
}
publicvoid run()
{
while(true)
{
res.out();
}
}
}