一.线程安全

如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

通过电影院卖票,演示线程的安全问题:

模拟电影院的卖票过程。本次电影的座位共100个(本场电影只能卖100张票)。模拟电影院的售票窗口,实现多个窗口同时卖这场电影票(多个窗口一起卖这100张票)

需要窗口,采用线程对象来模拟;需要票,Runnable接口子类来模拟

//测试类
public class ThreadDemo {public static void main(String[] args) {//创建票对象Ticket ticket = new Ticket();//创建3个窗口Thread t1  = new Thread(ticket, "窗口1");Thread t2  = new Thread(ticket, "窗口2");Thread t3  = new Thread(ticket, "窗口3");t1.start();t2.start();t3.start();}
}

//模拟票
public class Ticket implements Runnable {//共100票int ticket = 100;public void run() {//模拟卖票while(true){if (ticket > 0) {//模拟选坐的操作try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);}}}

运行结果发现:

①票出现了重复的票

②错误的票 0、-1

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

二.线程同步(线程安全处理Synchronized)

java中提供了线程同步机制,它能够解决上述的线程安全问题。

线程同步的方式有两种:

①同步代码块

②同步方法

1.同步代码块

//同步代码块: 在代码块声明上 加上synchronized
synchronized (锁对象) {可能会产生线程安全问题的代码
}

同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。

//使用同步代码块,对电影院卖票案例中Ticket类进行如下代码修改:
public class Ticket implements Runnable {//共100票int ticket = 100;//定义锁对象Object lock = new Object();@Overridepublic void run() {//模拟卖票while(true){//同步代码块synchronized (lock){if (ticket > 0) {//模拟电影选坐的操作try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);}}}}
}

2.同步方法

//同步方法:在方法声明上加上synchronized
public synchronized void method(){可能会产生线程安全问题的代码
}

同步方法中的锁对象是 this

//使用同步方法,对电影院卖票案例中Ticket类进行如下代码修改:
public class Ticket implements Runnable {//共100票int ticket = 100;//定义锁对象Object lock = new Object();@Overridepublic void run() {//模拟卖票while(true){//同步方法
            method();}}//同步方法,锁对象thispublic synchronized void method(){if (ticket > 0) {//模拟选坐的操作try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);}}
}

//静态同步方法: 在方法声明上加上static synchronized
public static synchronized void method(){
可能会产生线程安全问题的代码
}

静态同步方法中的锁对象是 类名.class

转载于:https://www.cnblogs.com/akiyama/p/10209173.html

java多线程(线程安全,线程同步)相关推荐

  1. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  2. Java多线程之守护线程实战

    转载自 Java多线程之<<守护线程>>实战 定义 什么是守护线程?与守护线程相对应的就是用户线程,守护线程就是守护用户线程,当用户线程全部执行完结束之后,守护线程才会跟着结束 ...

  3. Java多线程设计模式(4)线程池模式

    前序: Thread-Per-Message Pattern,是一种对于每个命令或请求,都分配一个线程,由这个线程执行工作.它将"委托消息的一端"和"执行消息的一端&qu ...

  4. java多线程抽奖_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码...

    导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...

  5. 掌握JAVA多线程的利器-线程池

    为什么80%的码农都做不了架构师?>>>    相信大多数接触过多线程的朋友都会有这样的困惑,明明使用了多线程,为何还是一团糟?用下面两幅图再合适不过了: 理想情况下的多线程VS 现 ...

  6. java多线程问题,线程交替执行

    两个线程,一个打印1-100的奇数,一个打印1-100的偶数:要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环. package threadtest;publ ...

  7. Java多线程之暂停线程

    暂停线程 暂停线程意味着此线程还可以恢复运行.在Java多线程中,suspend()方法可以暂停线程,resume()方法可以恢复线程. 这两个方法都是已经过时的方法. 1.8.1suspend与re ...

  8. 【Java多线程】了解线程的锁池和等待池概念

    文章目录 一.内置锁 二.线程状态 线程的5种状态 线程状态图 线程释放锁的情况 线程阻塞和线程等待的区别 sleep.join.yield.wait区别 yield不释放锁案例 sleep不释放锁案 ...

  9. java多线程并发及线程池

    线程的常用创建方式 1.继承Thread类创建线程类 public class FirstThreadTest extends Thread {public void run(){System.out ...

  10. Java多线程学习(二)---线程创建方式

    线程创建方式 摘要: 1. 通过继承Thread类来创建并启动多线程的方式 2. 通过实现Runnable接口来创建并启动线程的方式 3. 通过实现Callable接口来创建并启动线程的方式 4. 总 ...

最新文章

  1. tflearn anaconda 安装过程记录
  2. swift 1.2 升级
  3. 阿里巴巴大数据之路——数据模型篇
  4. 7、Power Map—实例:添加二维数据表以及批注
  5. 呕心沥血为小白总结13个学习网站-错过了你注定绕弯!
  6. C# 快速高效率复制对象另一种方式 表达式树
  7. Java中的subList方法
  8. leetcode69. x 的平方根(二分法)
  9. 【资源】吴恩达新书《Machine Learning Yearning》完整中文版免费下载
  10. python filecmp
  11. 约瑟夫(环)问题(Josephus problem)
  12. xposed框架android9.0,xposed仓库商店下载
  13. 计算机答辩ppt演讲稿,毕业答辩PPT演讲稿开场白
  14. 全国计算机二级重难点,计算机二级office重难点.doc
  15. win8 计算机内存不足怎么办,如何解决Win8电脑内存不足的问题?
  16. 嵌入式技术的前沿应用领域
  17. fiddle无法抓包小程序解答
  18. java汉字转拼音pinyin4j-2.5.0.jar用法
  19. 企业管理新标杆:向对手学习
  20. 三子棋——可修改为多子棋

热门文章

  1. 《Microsoft SQL Server 2008 Analysis Services Step by Step》学习笔记十一:与Cube交互(下)...
  2. 哪几种人会被房价拐点忽悠
  3. jqgrid 固定列宽度_jqGrid 设置列宽
  4. Linux服务器性能的重要指标:打开文件数的限制
  5. 利用bug来进行调试
  6. java中到底有没有指针?
  7. java: 非法字符: ‘\ufeff‘、java: 需要class, interface或enum
  8. 【渝粤教育】国家开放大学2018年春季 0045-21T烹饪原料学(1) 参考试题
  9. [渝粤教育] 西南科技大学 语言学概论(汉语言文学) 在线考试复习资料
  10. DCGAN-深度卷积生成对抗网络-转置卷积