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

来源:互联网 发布:录屏直播软件 编辑:程序博客网 时间:2024/06/05 04:34

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

        }

}

}

0 0