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的占有权 最终会有一个占有 其他线程继续等待
下面讨论一个典型问题 生产者和消费者模式
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式
什么是生产者消费者模式
这里要引用阻塞队列 ,当生产者生成数据时放入阻塞队列里,消费者从阻塞队列里拿数据,而不找生产者拿数据从阻塞缓冲区里拿数据
生成者和消费者是解决二者之间阻抗效率问题,耦合只是附带的
实例
一个馒头店,厨师生产馒头,放到篮子里,客人从里面拿然后吃掉,当篮子满时 厨师让客人来吃,当篮子空时 让厨师生产
- 生产的物品馒头
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(); }}
- Java---并发和同步(生产者--消费者)
- 【java 多线程】多线程并发同步问题及生产者、消费者问题
- Java实现同步机制(生产者消费者)
- 生产者和消费者(Java)
- Java 生产者消费者并发实例
- java生产者消费者多线程同步
- java生产者消费者同步问题
- 线程同步生产者和消费者c和java不同实现
- java 生产者和消费者
- Java 生产者和消费者
- Java生产者和消费者
- java实现 生产者和消费者问题 多线程同步示例
- 学习和理解JAVA线程同步--生产者与消费者例子
- 学习和理解JAVA线程同步--生产者与消费者例子
- java实现线程同步一个生产者和一个消费者
- JAVA线程同步——消费者和生产者模式
- Java 并发编程(四)阻塞队列和生产者-消费者模式
- (十六)java并发编程--线程的死锁解决方案(生产者和消费者几种实现方式)
- web.xml配置详解之context-param
- Python编辑器设置(包括Visual Studio Code和Sublime Text3)
- 收藏网站79
- windows 下python安转numpy、opencv包
- try catch异常后,spring的异常是否还有效
- Java---并发和同步(生产者--消费者)
- JSON.net的转换操作
- hdu 1019 Least Common Multiple
- 使用RadioButton和RadioGroup实现多种多样的单选情况
- 正则表达式查找
- Oracle学习笔记(4)------------简单查询
- 配置使用log4j-1.2.17
- delete运算符(删除对以前定义的对象的属性和方法的引用)
- 程序编译过程