您的位置:首页 > 数据库 > Oracle

java+oracle+web(第八天) java 基础课程(二) 多线程同步和死锁(2个线程、四个线程)

2015-05-24 21:53 489 查看

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();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐