您的位置:首页 > 职场人生

集合框架Collection的若干知识点--黑马程序员

2014-08-13 17:05 225 查看
在java中多线程之间的通信,本篇主要说明的是多线程之间的通信,共同操作一个资源,以及线程中出现的死锁现象,以及出现线程中重复生产的问题,通过同步线程可以解决这些问题,同步线程同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。
由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。

这下面的代码中都可以详细的体现出来,其代码如下:

public class ProducerCustumerDemo {

 /**

  * @param args

  */

 public static void main(String[] args) {

  //着这里传建一个资源类,是为了多线程之间保持操作的是一个资源,用构造函数等的方式传递到线程类中

  Resouce resouce=new Resouce();

  //创建多个生产和消费的线程类

  Producer producer1=new Producer(resouce);

  Producer producer2=new Producer(resouce);

  Custumer custumer1=new Custumer(resouce);

  Custumer custumer2=new Custumer(resouce);

  

  new Thread(producer1).start();

  new Thread(producer2).start();

  new Thread(custumer1).start();

  new Thread(custumer2).start();

 }

 //定义一个线程共享的一个资源类

 static class Resouce{

  //商品的ID

  private int id;

  //商品的名字

  private String name;

  //用于判断是否生产或者消费的数据,

  private boolean flag=false;

  

  //同步方法,是为了线程之间保持数据的一致性,不会出现意外的情况发生

  public synchronized void set(String name)

  {

   //这里用while循环是为了防止多个线程,重复生产的情况

   while(flag)

    try {

     this.wait();//线程等待,也即是放弃运行的资格

    } catch (Exception e) {

     // TODO: handle exception

    }

   this.name=name+id++;

   //获取当前线程的名称

   String currentThread=Thread.currentThread().getName();

   System.out.println(currentThread+"生产"+this.name+"....");

   //消费之后,让消费的线程继续消费该商品

   this.flag=true;

   this.notifyAll();

  }

  

  public synchronized void out()

  {

   //这里用while循环是为了防止多个线程,多消费情况

   while(!flag)

    try {

     this.wait();//线程等待,也即是放弃运行的资格

    } catch (Exception e) {

     // TODO: handle exception

    }

   //获取当前线程的名称

   String currentThread=Thread.currentThread().getName();

   System.out.println(".........."+currentThread+"消费了"+this.name);

   //消费之后,让生产的线程继续生产产品

   this.flag=false;

   //唤醒线程池中的线程,这里不用notiy()是因为这里可能出现死锁的现象

   this.notifyAll();

  }

 }

 

 //生产商品的线程类

 static class Producer implements Runnable{

  //顶一个资源类对象

  Resouce resouce=null;

  public Producer(Resouce re) {

   this.resouce=re;

  }

  @Override

  public void run() {

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

   resouce.set("小米电视");

  }

 }

 

 //消费商品的线程类

 static class Custumer implements Runnable{

  Resouce resouce=null;

  public Custumer(Resouce re) {

   this.resouce=re;

  }

  public void run() {

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

   resouce.out();

  }

  

 }

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