Java---并发和同步(生产者--消费者)

来源:互联网 发布:2017淘宝刷法爆款 编辑:程序博客网 时间:2024/06/05 07:38

并发:这里先说下进程和线程的区别 :
一个程序至少需要一个进程一个线程,进程是独立于内存 ,线程是共享于内存 ,并发性高 也就是说 线程只能是在应用中存在。
并发性在程序里指多个线程同时访问,然java是通过时间片化,实现多线程的 也就是并发 。
同步
线程同步 是指一个线程对象同一时间在同一个方法里执行一次
买票问题 :首先票是唯一的 而买票窗口是N个 如果不同步,那么很有可能一张票卖给两个人,解决这个问题 就是在销售票时 后面的线程进入阻塞状态,等前面的线程结束 释放之后 再进行买票 ` class Threadss implements Runnable {

private  int a=6666;public void run(){    for (int i = 0; i <100000; i++) {        if(a>0){            System.out.println("售票编号 "+a--);        }    }}

}`

public static void main(String[] args) {        Threadss a=new Threadss();        Threadss b=new Threadss();        Threadss c=new Threadss();        a.run();        b.run();        /*b.run();        c.run();*/

那么什么是阻塞呢?这里我们要必须知道一个问题 那就是对象监视器 monitor 很多地方称为锁 java规定每个对象都有一个锁 ,而且这个锁只有在同步块里才能被正确使用
synchronized 里面 :锁 只能有被一个线程占用,后面不管有多个,都只能等待,只有该线程使用完 才能释放 ,也有这样一种情况 。例如有一个同步方法 method(); 里面有两个实例 a b 同一时刻a.method() 和b,method() 不冲突 都能完美的调用
所以买票的逻辑在同步块里实现 那么就不会出现一张票两个人的问题
synchronized特点:
1、放方法名前是同步方法 放在块前是同步块
2、当作为块时不能放在if 后面。
锁和同步时注意的
(1)只能同步方法 不能同步变量和类
(2)同步方法所在的类 可以有非同步的方法 程序需要同步时就加synchronized
(3)如果一个线程拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁限制
(4)线程可以获得多个锁,一个对象的同步方法里面调用另一个对象的同步方法,则获得两个对象的监视器
(5)同步损坏并发性, 同步不仅同步某个方法,还可以同步方法里的末以块
(6)同步静态的方法,则需要把整个类都加上锁 synchronized
wait notify() notifyAll()的使用

wait()
使本线程挂起 挂起的对象将释放montor ,只有其他线程使用notify 和 notifyAll 才能被唤醒使用
notify()
是随机唤醒一个线程
notifyAll()
唤醒所有该对象的沉睡线程,唤起的线程会继续争夺monitor的占有权 最终会有一个占有 其他线程继续等待
下面讨论一个典型问题 生产者和消费者模式
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式
什么是生产者消费者模式
这里要引用阻塞队列 ,当生产者生成数据时放入阻塞队列里,消费者从阻塞队列里拿数据,而不找生产者拿数据从阻塞缓冲区里拿数据
生成者和消费者是解决二者之间阻抗效率问题,耦合只是附带的
实例
一个馒头店,厨师生产馒头,放到篮子里,客人从里面拿然后吃掉,当篮子满时 厨师让客人来吃,当篮子空时 让厨师生产

  1. 生产的物品馒头
package org.com.action;/** * 生产的数据  例如馒头 * @author wangfeng * */public class Mantou {   private int index;   //有参构造方法 public Mantou(int index){     this.index=index;  } //重写toString 输出 public String toString(){    return "Mantou--"+index; }

2、篮子

package org.com.action;public class Basket {    private int i=0; //表示装第几个馒头    private  Mantou[] mantou=new Mantou[6];  //篮子的数量    //生成者    public synchronized void pro(Mantou m){        //这里当篮子满时提示客人来吃        while(i==mantou.length){              try {                  System.out.println("篮子满了");                this.wait(); //线程暂停,等待唤醒            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }         System.out.println(Thread.currentThread().getName()+"生成"+m.toString());         this.notify(); //生产完,唤醒线程         mantou[i]=m;  //把馒头塞进篮子里         i++;    }    //消费者    public synchronized Mantou con(){         while(i==0){             try {                 System.out.println("篮子空");                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }         }         Mantou is=mantou[--i];         System.out.println(Thread.currentThread().getName()+"消费"+is.toString());         this.notify();         return is;    }}

3 厨师

package org.com.action;/** * 生产者 * @author wangfeng * */public class Produce implements Runnable {  private  Basket b;  public Produce(Basket b){      this.b=b;  }    @Override    public void run() {        // TODO Auto-generated method stub        for (int i = 0; i <20; i++) {            Mantou m=new Mantou(i);            b.pro(m);            try {                Thread.sleep(500);//阻塞线程            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

4 消费者

package org.com.action;public class Consumer implements Runnable {  private Basket b;  public Consumer(Basket b){      this.b=b;  }    @Override    public void run() {        // TODO Auto-generated method stub        for (int i = 0; i < 20; i++) {            Mantou m=b.con();             try {                Thread.sleep(1000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

5 mian

package org.com.action;public class ThreeClass {        public static void main(String[] args) {         Basket b=new Basket();          new Thread(new Produce(b)).start();          new Thread(new Consumer(b)).start();        }}
0 0
原创粉丝点击