目录标题

  • 解决线程安全问题手段:线程同步
    • 实现同步操作步骤
      • 1.同步代码块
      • 2.同步方法
      • 静态同步方法
      • 3.Lock接口的锁机制
  • 线程状态
  • 生产者消费者模型:等待唤醒
  • 等待唤醒案例

线程安全问题是不能产生的,我们可以让一个线程在访问共享数据的时候,无论是否失去了cpu的执行权,让其他的线程只能等待,等待当前线程执行完,其他线程在执行
保证始终是一个线程在执行

解决线程安全问题手段:线程同步

实现同步操作步骤

1.同步代码块

格式:
synchronized(锁对象){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
注意事项:
1.通过代码块中的锁对象,可以使用任意的对象
2.但是必须保证多个线程使用的锁对象是同一个
3.锁对象作用:
把同步代码块锁住,只让一个线程在同步代码块中执行
创建Runnable的实现类RunnableImple

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {private int ticket = 100;//创建一个锁对象Object obj = new Object();@Overridepublic void run() {while (true){//同步代码块synchronized (obj){if (ticket>0){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);ticket--;}}}}
}

主程序

public class t1 {public static void main(String[] args){RunnableImple rnb = new RunnableImple();new Thread(rnb).start();new Thread(rnb).start();new Thread(rnb).start();}
}

同步技术原理:
同步中的线程,没有执行完毕不会释放锁,同步外的线程没有锁进不去同步
弊端
同步保证了只能有一个线程在同步中执行共享数据保证了数据
程序频繁的判断锁,释放锁,程序的效率会降低

2.同步方法


使用步骤:
1.把访问就共享数据的代码抽取处理,放到一个方法中
2.在方法上添加synchronized修饰符
创建Runntable实现类RunnableImple

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {private int ticket = 100;@Overridepublic void run() {while (true){payTicket();}}public synchronized void payTicket(){if (ticket>0){System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);ticket--;}}
}

主程序

public class t1 {public static void main(String[] args){RunnableImple rnb = new RunnableImple();new Thread(rnb).start();new Thread(rnb).start();new Thread(rnb).start();}
}

静态同步方法

Runnable实现类RunnableImple

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {private static int ticket = 100;@Overridepublic void run() {while (true){payTicket();}}public static synchronized void payTicket(){if (ticket>0){System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);ticket--;}}
}

主程序

public class t1 {public static void main(String[] args){RunnableImple rnb = new RunnableImple();new Thread(rnb).start();new Thread(rnb).start();new Thread(rnb).start();}}

静态同步方法锁对象不能是this,this是创建对象之后产生的,静态方法要优先于对象
静态方法的锁对象是RunnableImple.class属性

3.Lock接口的锁机制


使用步骤:

创建Runnable实现类RunnableImple

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {private static int ticket = 100;//1.创建ReentrantLock对象Lock l = new ReentrantLock();@Overridepublic void run() {while (true){l.lock();try {Thread.sleep(10);if (ticket>0){System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket);ticket--;}} catch (InterruptedException e) {e.printStackTrace();}finally {l.unlock();}}}
}

主程序

public class t1 {public static void main(String[] args){RunnableImple rnb = new RunnableImple();new Thread(rnb).start();new Thread(rnb).start();new Thread(rnb).start();}}

线程状态

生产者消费者模型:等待唤醒

等待唤醒案例


notify()唤醒一个等待时间最久的线程
notifyall()唤醒所有等待线程

public class t1 {public static void main(String[] args){//创建锁对象Object obj = new Object();//顾客new Thread(){@Overridepublic void run() {while (true){//一直等待买包子//保证等待和唤醒只能有一个执行synchronized (obj){System.out.println("点餐");try {obj.wait();} catch (InterruptedException e) {e.printStackTrace();}//唤醒之后执行的代码System.out.println("端上桌开吃");System.out.println("-----------");}}}}.start();new Thread(){@Overridepublic void run() {while (true){try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (obj){System.out.println("告知顾客取餐");obj.notify();}}}}.start();}}




创建一个资源类:包子类

public class rube {//皮String skin;String stuffing;boolean state = false;
}

创建生产者类:包子铺类

public class productionImpl extends Thread {private rube bz;public productionImpl(rube bz) {this.bz = bz;}@Overridepublic void run() {int count = 0;while (true){synchronized (bz){if (bz.state==true){try {bz.wait();} catch (InterruptedException e) {e.printStackTrace();}}if (count%2==0){bz.skin="薄皮";bz.stuffing="三鲜";}else{bz.skin="冰皮";bz.stuffing="牛肉";}count++;System.out.println("包子正在制作:"+bz.skin+bz.stuffing+"包子");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}bz.state=true;bz.notify();System.out.println("包子已经出锅上桌了 ");}}}
}

创建消费者类:顾客类

public class consumerImple extends Thread {private rube bz;public consumerImple(rube bz) {this.bz = bz;}@Overridepublic void run() {while (true){synchronized (bz){if (bz.state==false){try {bz.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("正在吃"+bz.skin+bz.stuffing+"的包子");bz.state=false;bz.notify();System.out.println("吃完了所有的包子,赶紧上菜!");}}}
}

主程序

public class t1 {public static void main(String[] args){rube bz = new rube();new productionImpl(bz).start();new consumerImple(bz).start();}}

java-线程安全问题,线程实现线程同步,线程状态,等待唤醒机制,生产者消费者模型相关推荐

  1. 线程同步之 生产者消费者模型详解

    前言 博主本来没打算讲这个比较前面的知识的(博主socket编程还有两个部分没讲,进程也才写完回收僵尸进程的三种方法,信号捕捉器也才完结),但是今天有朋友来问博主,什么是生产者消费者模型,所以博主就先 ...

  2. 锁, threading.local, 线程池, 生产者消费者模型

    一. 锁:Lock (1次放1个) 线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue     线程不安全 + 人 => 排队处理. 需求:         a ...

  3. 如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. wait, notify 和 noti ...

  4. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

  5. 【Java 并发编程】多线程、线程同步、死锁、线程间通信(生产者消费者模型)、可重入锁、线程池

    并发编程(Concurrent Programming) 进程(Process).线程(Thread).线程的串行 多线程 多线程的原理 多线程的优缺点 Java并发编程 默认线程 开启新线程 `Ru ...

  6. 27_多线程_第27天(线程安全、线程同步、等待唤醒机制、单例设计模式)_讲义...

    今日内容介绍 1.多线程安全问题 2.等待唤醒机制 01线程操作共享数据的安全问题 *A:线程操作共享数据的安全问题如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程 ...

  7. 27_多线程_第27天(线程安全、线程同步、等待唤醒机制、单例设计模式)

    今日内容介绍 1.多线程安全问题 2.等待唤醒机制 01线程操作共享数据的安全问题 *A:线程操作共享数据的安全问题如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程 ...

  8. java基础提升(二):多线程、线程安全、线程状态、等待唤醒机制、线程池

    目录 一. 多线程 1.1并发与并行 1.2 线程与进程 1.3 创建线程类 1.3.1 方式一:继承Thread类 1.3.2 方式二:实现Runnable接口 1.3.3 Thread和Runna ...

  9. Java线程等待唤醒机制(加深理解)

    今天看源码的时候遇到这样一个场景,某线程里面的逻辑需要等待异步处理结果返回后才能继续执行.或者说想要把一个异步的操作封装成一个同步的过程.这里就用到了线程等待唤醒机制,下面具体看一下. 等待唤醒机制示 ...

最新文章

  1. graylog - collecting Failed and Accepted logins for your SSH
  2. Android编译32或64位程序
  3. Windows下C/C++获取当前系统时间
  4. koa --- [MVC实现之三]换个角度重新开始-初始化
  5. LeetCode 38. 报数
  6. win7系统电脑d盘不见了的解决方法
  7. WebSocket 协议
  8. GDI和GUI的区别
  9. Java实现文件批量重命名
  10. C++11多线程中的detach()、join()、joinable()
  11. java api es_中间件系列之ElasticSearch-3-Java API操作ES
  12. R语言 openair 做后向轨迹
  13. java题库管理考试管理源码,基于jsp的题库管理系统-JavaEE实现题库管理系统 - java项目源码...
  14. 周鸿祎:人人需要Mentor,世界没有奇迹
  15. 外联css不生效,css外联样式不起作用的解决方法
  16. 创新专题一:省份层面(创新效率、创新能力、投入产出、高质量发展等)
  17. Secure CRT 用域名连接虚拟机的详细步骤
  18. AI产品经理-人工智能的发展
  19. 悟透JavaScript之对象素描
  20. 【从FT到DFT和FFT】(一)从三角函数正交性到傅里叶变换的详细公式推导

热门文章

  1. [持续更新中]博客园开放api、还有知乎、V2EX开放接口
  2. 一年之计在于春,一日之计在于晨,劲爆
  3. 2015人大计算机复试线,清华、北大、人大、公布2015年考研复试线
  4. python输入生日输出生肖_用Python输入年月日 输出X年X月X日生肖是XX,xx岁的XX星座...
  5. 学习英文-学以致用【场景:吃饭与家务】
  6. 经典C语言程序设计100例,部分有个人注解
  7. 【pytorch】将模型部署至生产环境:借助TorchScript跟踪法及注释法生成可供C++调用的模块
  8. 在header中添加中文头信息
  9. Aspose.Words开发者指南
  10. VSCode 环境配置管理