进程定义:

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位

线程定义:

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

线程运行图:

线程有三种创建方式

1实现Runnable接口

2 继承Thread类

3使用Callable和Future接口创建线程。具体是创建Callable接口的实现类,并实现clall()方法。并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建线程。

线程的一些方法:  

  守护线程 执行一些非业务方法,比如gc。当全部都是守护线程的时候,jvm退出

  线程优先级  设置线程优先级:setPriority(int priorityLevel)。参数priorityLevel范围在1-10之间,值越大优先级越高,

    能被执行到的概率越大,但非优先执行。

  sleep() 让当前的正在执行的线程暂停指定的时间,并进入阻塞状态 时间到了,恢复到就绪状态

  join() 等待线程结束,我执行完了 你才能执行

   yield() 谦让,我暂时不执行,我回到就绪状态

另外 yield()方法还与线程优先级有关,当某个线程调用yiled()方法从运行状态转换到就绪状态后,CPU从就绪状态线程队列中只会选择与该线程优先级相同或优先级更高的线程去执行。但是分配还是随机的 可能还是执行到原来的线程

线程的生命周期

    新建状态(New):当线程对象对创建后,即进入了新建状态

    就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,能否在执行需要看待cpu的调度。

    运行状态(Running):cpu调度到该线程,该线程就会运行。

    阻塞状态(Blocked):线程因为某些原因,暂时被挂起,暂时不继续执行的状态。常见的有以下三种

      1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

      2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

      3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

注:

    只有使用yield()方法以后 线程从运行到就绪状态

    无论使用 wait(),sleep(), join() 都是先进入阻塞 当满足了相关条件以后,在进入就绪状态

线程交互

    1使用wait()、notify()和notifyAll()时需要首先对调用对象加锁【必须使用在同步代码块】   
    2调用wait()方法后,线程状态会从RUNNING变为WAITING,并将当线程加入到lock对象的等待队列中【会释放锁】 ,后面的代码就不执行了 。当被唤醒并被执行时,是接着上次执行到的wait()方法代码后面继续往下执行的。
    3调用notify()或者notifyAll()方法后(不会释放锁),等待在lock对象的等待队列的线程不会马上从wait()方法返回,必须要等到调用notify()或者notifyAll()方法的线程将lock锁释放,等待线程才有机会从等待队列返回。这里只是有机会,因为锁释放后,等待线程会出现竞争,只有竞争到该锁的线程才会从wait()方法返回,其他的线程只能继续等待

生产者线程:

如果水果的数量在[0,9]则开始生产,否则转到消费线程。

public class Producer implements Runnable {private Fruit fruit;public Producer() {super();}public Producer(Fruit fruit) {super();this.fruit = fruit;}public Fruit getFruit() {return fruit;}public void setFruit(Fruit fruit) {this.fruit = fruit;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){synchronized (fruit) {//积压了10个水果未卖出去  停掉生产的线程等待卖出去    if(fruit.getNumber()>=10){try {fruit.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block
                        e.printStackTrace();}}if(fruit.getNumber()>=0&&fruit.getNumber()<10){try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch block
                        e.printStackTrace();}System.out.println(fruit.getName()+"被生产出来了");fruit.setNumber(fruit.getNumber()+1);System.out.println("当前水果数量为"+fruit.getNumber());fruit.notify();}}    }}}

消费者线程:

如果水果的数量在大于0,即可消费,否则转到生产线程

public class Customer implements Runnable {private Fruit fruit;public Customer() {super();}public Customer(Fruit fruit) {super();this.fruit = fruit;}public Fruit getFruit() {return fruit;}public void setFruit(Fruit fruit) {this.fruit = fruit;}@Overridepublic void run() {while(true){//处理并发问题synchronized (fruit) {//判断水果的数量是否>0;if(fruit.getNumber()>0){try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(fruit.getName()+"被买走了");//减少水果数量fruit.setNumber(fruit.getNumber()-1);System.out.println("当前水果数量为"+fruit.getNumber());fruit.notify();}else{try {//水果已经卖完拿了 等待生产fruit.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}}

Fruit类

public class Fruit {private int number;private String name;public Fruit() {super();}public Fruit(int number, String name) {super();this.number = number;this.name = name;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

当调用obj.notify()/notifyAl0()l后,调用线程依旧持有obj锁,当调用obj.wait()后,调用线程会释放obj锁,如果将synchronized (fruit)放在while(true)前面,会因为同步锁未及时释放,一直运行到obj.wait()才释放同步锁。  如果用的synchronized 同步代码块  在当运行到while结束循环的break时会自动释放锁  ,而用lock时 不会自动释放锁,  synchronized在实现runable接口时  修饰在方法上  锁对象用this   而继承类Thread时 修饰在静态方法上锁对象表示当前类的类对象

public class SalesThread implements Runnable{//这个类本身就会被共享  故变量不用再加staticprivate int tickets=100;public SalesThread(){}@Overridepublic void run() {while(true){if(tickets>0){ff();}else{System.out.println("票已售完!");break;}}    }public void ff1(){synchronized(this){try {Thread.sleep(200);System.out.println(Thread.currentThread().getName()+"正在卖第"+(tickets--)+"张票");} catch (InterruptedException e) {// TODO Auto-generated catch block
                e.printStackTrace();}    }}

Sleep方法会先进行阻塞,然后休眠到期就会进去就绪状态

转载于:https://www.cnblogs.com/MyJavaStudy/p/9020219.html

java多线程-生产者消费者模式相关推荐

  1. Java多线程-生产者消费者问题(多个消费者多个生产者)

    Java多线程-生产者消费者问题(多个消费者多个生产者) public class ConsumerProcuderDemo {public static void main(String[] arg ...

  2. Java多线程——生产者消费者问题

    创建多个线程去执行不同的任务,如果这些任务之间有着某种关系,那么线程之间必须能够通信来协调完成工作. 生产者消费者问题(英语:Producer-consumer problem)就是典型的多线程同步案 ...

  3. 【Java】生产者消费者模式的三种实现

    原文地址:https://blog.csdn.net/u010983881/article/details/78554671 前言 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内 ...

  4. 【Java】生产者消费者模式的实现

    前言 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据. 阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力.这个 ...

  5. java实现生产者消费者模式

    一: 什么是生产者消费者模型 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直 ...

  6. 【JAVA】生产者消费者模式

    首先要思考一个问题:为什么要使用这种模式进行生产代码. 优点: 极大的解决了代码之间的耦合程度 解释: 之前我们写的代码可能是这样的,有A和B 两个功能代码处理数据,B代码的执行必须要依赖于A代码才能 ...

  7. java多线程 生产者消费者_java多线程之-生产者与消费者

    java多线程之-并发协作[生产者与消费者]模型 对于多线程程序来说,不管c/c++ java python 等任何编程语言,生产者与消费者模型都是最为经典的.也就是可以说多线程的并发协作 对于此模型 ...

  8. Java多线程生产者消费者调度实现

    生产者消费者模型是多线程中最常见的模型,有着广泛的应用.其主要目的是实现一种动态的平衡,让生产者消费者和谐共处,获得最大化的执行效率. 所说的动态平衡其实就是生产者与消费者协作控制仓储,让消费者不至于 ...

  9. java 实现生产者-消费者模式

    生产和消费者模式有很多种,现在介绍几种常见的方式 wait/notify实现生产和消费者模式 1.使用wait/notify实现生产和消费者模式: public class Depot {// 实际容 ...

最新文章

  1. 硬货 | 一文解读完五篇重磅ACL2017 NLP论文
  2. lua学习笔记之闭包
  3. MongoDB · 引擎特性 · MongoDB索引原理
  4. Android自动填充短信验证码
  5. 《大话数据结构》第9章 排序 9.3 冒泡排序(上)
  6. NYOJ 248 BUYING FEED (贪心)
  7. 接下来学习计划2020.11.9
  8. SQL实战篇:SQL解决近X天的问题
  9. Redis 单例、主从模式、sentinel 以及集群的配置方式及优缺点对比(转)
  10. 扩展easyui tree的两个方法 获取实心节点
  11. Eclipse断点调试
  12. C++ STL 容器的一些总结
  13. cpu占用高 mongo_排查MongoDB CPU使用率高的问题
  14. SVN系列二 SVN的安装配置(linux)
  15. 伺服舵机基础知识汇总
  16. 2022年版中国污泥处理处置行业投资现状与前景规划分析报告
  17. 手机科学计算机xy怎么用,如何使用科学计算器
  18. PS网页设计_新手建站入门视频教程
  19. <a>链接下载视频 而不是打开新页面播放
  20. MATLAB初阶绘图

热门文章

  1. 《mysql 必知必会》 笔记(五)
  2. 关于u-boot中的.balignl 16,0xdeadbeef的理解
  3. 代码生成工具之数据库表及字段名称转义
  4. Mysql数据库及帐号的权限查询
  5. 进程间通信 - 整理
  6. 【Vegas原创】Can't connect to X11 window server using ':0.0' 解决方法
  7. [习题]如何触发 GridView 身体里面的「子控件」的事件 (ASP.NET案例精编 / 清华大学出版社 Ch.10/11两章的补充)...
  8. 单调栈与单调队列简单例题
  9. (Java) Md5Utils
  10. RLock(递归锁)