之生产者与消费者问题,Lock和Condition,线程面试题

来源:互联网 发布:淘宝联盟qq群推广 编辑:程序博客网 时间:2024/05/01 09:43


生产者和消费者

package com.sdut.day4;

 

class Resource1

{

      private Stringname;

      privateintcount = 1;

      booleanflag =false;

      publicsynchronized void set(String name)

      {

          while(flag)

          {

                try {

                     this.wait();

                }catch (InterruptedException e){

                     //TODO Auto-generated catchblock

                     e.printStackTrace();

                }

          }

          this.name = name+count;

          count++;

          System.out.println(Thread.class.getName()+"生产者"+this.name);

          flag =true;

          this.notifyAll();

          

      }

      publicsynchronizedvoid out()

      {

          while(!flag)//while判断标记,解决了线程获取执行权后,是否要执行

          {

                try {

                     this.wait();

                }catch (InterruptedException e){

                     //TODO Auto-generated catchblock

                     e.printStackTrace();

                }

          }

          System.out.println(Thread.class.getName()+"------------消费者"+this.name);

          flag =false;

          this.notifyAll();//解决了,本方线程一定会唤醒对方线程

      }

}

class Producerimplements Runnable

{

      private Resource1 r ;

      Producer(Resource1  r)

      {

          this.r = r;

      }

     

      publicvoid run()

      {

          while(true)

          {

                r.set("烤鸭");

          }

      }

}

class Consumerimplements Runnable

{

      private Resource1r ;

      Consumer(Resource1 r)

      {

          this.r = r;

      }

      publicvoid run()

      {

          while(true)

          {

                r.out();

          }

      }

}

 

publicclass ProducerConsumer {

 

      publicstaticvoid main(String[] args) {

          Resource1r =new Resource1();

          Producerp1 =new Producer(r);

          Consumerc1 =new Consumer(r);

          Thread t0=new Thread(p1);

          Thread t1=new Thread(p1);

          Thread t2=new Thread(c1);

          Thread t3=new Thread(c1);

          t0.start();

          t1.start();

          t2.start();

          t3.start();

      }

 

}

Lock   Condition

自从jdk1.5以后将同步和锁封装成了对象,并将操作锁的隐士方式变成了显式

Lock lock = new ReentrantLock();

Void show

{

      Lock.lock();//获取锁

      Code….

      Lock.unlock();//释放锁常常放在finally里面

}

 

package com.sdut.day4;

 

importjava.util.concurrent.locks.Condition;

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

 

class Resource1

{

      private Stringname;

      privateintcount = 1;

      booleanflag =false;

      Lock lock1 = new ReentrantLock();//创建一个锁对象。替代了同步代码块

      //通过已有的锁对象来获取该锁上的监视器对象

      //锁和监视器分离。设置一个锁,不同的监视器

      Condition con1 = lock1.newCondition();//生产者的监视器

      Condition con2 = lock1.newCondition();//消费者的监视器

      public  void set(String name)

      {

          

          try{

                lock1.lock();

                while(flag)

                {

                     try {

                           con1.await();

                     }catch (InterruptedException e){

                           //TODO Auto-generated catchblock

                           e.printStackTrace();

                     }

                }

                this.name = name+count;

                count++;

                System.out.println(Thread.class.getName()+"生产者"+this.name);

               flag =true;

                con2. signal ();//唤醒所有处于该监视下的线程

          }

          finally

          {

                lock1.unlock();

          }

          

      }

      public void out()

      {

          try

          {

                lock1.lock();

                while(!flag)//while判断标记,解决了线程获取执行权后,是否要执行

                {

                     try {

                           con2.await();

                     }catch (InterruptedException e){

                           //TODO Auto-generated catchblock

                           e.printStackTrace();

                     }

                }

                System.out.println(Thread.class.getName()+"------------消费者"+this.name);

                flag =false;

                con1. signal ();//解决了,本方线程一定会唤醒对方线程

          }

          finally

          {

                lock1.unlock();

          }

 

      }

}

class Producerimplements Runnable

{

      private Resource1 r ;

      Producer(Resource1  r)

      {

          this.r = r;

      }

     

      publicvoid run()

      {

          while(true)

          {

                r.set("烤鸭");

          }

      }

}

class Consumerimplements Runnable

{

      private Resource1r ;

      Consumer( Resource1r)

      {

          this.r = r;

      }

      publicvoid run()

      {

          while(true)

          {

                r.out();

          }

      }

}

 

publicclass ProducerConsumer {

 

      publicstaticvoid main(String[] args) {

          Resource1r =new Resource1();

          Producerp1 =new Producer(r);

          Consumerc1 =new Consumer(r);

          Thread t0=new Thread(p1);

          Thread t1=new Thread(p1);

          Thread t2=new Thread(c1);

          Threadt3=new Thread(c1);

          t0.start();

          t1.start();

          t2.start();

          t3.start();

      }

 

}

Waitsleep区别

1.      wait可以指定时间也可以不指定,sleep必须指定时间

2.      在同步中,对cpu的执行权和锁的处理不同

Wait:释放执行权,并且释放锁。

Sleep:释放执行权,但是不释放锁

同步里面活着的线程可以不止一个,但是执行的只有一个,谁有锁谁执行

如何停止线程

任务中都会有循环结构,只要控制住循环就可以结束任务,可以使用标志

可以使用interrupt()法将线程从冻结状态强制恢复到运行状态钟来,让cpu具备执行资格

当强制制动会发生InterruptedException ,记着处理

SetDaemon(true) :后台线程,在线程开启之前定义线程为后台线程,如果所有前台线程都消失,则后台线程也跟着消失,

Join();进程要申请加入进来,运行。主线程要把资格释放出来

等到某个Join()的线程结束后,才能开始执行

例如:t1.start()  t2.start()   t1.join()则主线程需要等到t1线程运行结束后才能继续运行。

ToString()

线程的优先级:t2.setPriority(Thread.Max_PRIORITY)

Yield()

 

使用匿名类创建线程:

new Thread()

{

         publicvoid run()

         {

                   for(inti = 0 ;i < 20 ;i++){

                  

                   }

         }

}.start();

new Thread(

         newrunnabel()

                   {

                            publicvoid run()

                            {

                                     for(int i = 0 ;i<30 ;i++)

                                     {

                                     }

                            }

                   }

 

)

面试题:

class Test implements Runnable

{

         publicvoid run(Thread r)

         {

        

         }

}

该题会发生错误,错误出现在首行,因为没有实现Runnable这个借口的默认方法run(),应该被abstract修饰

class ThreadTest

{

         publicThread(

                   newRunnable()

                   {

                            publicvoid run()

                            {

                                     System.out.println("runnablerun");

                            }

                   }

         )

         {

                   publicvoid run()

                   {

                            System.out.println("subThreadrun");

                   }

         }

}

该题会打印,打印结果是subThread run因为,虽然runnable的子对象复写了Thread的默认的run方法,但是

Thread 的子类又覆盖了父类的run方法,所有最终打印的是子类的run方法

 

原创粉丝点击