线程安全问题
来源:互联网 发布:月饼事件 知乎 编辑:程序博客网 时间:2024/05/31 18:30
/* 需求: 模拟3个窗口同时在售50张 票 。 问题1 :为什么50张票被卖出了150次?出现 的原因: 因为num是非静态的,非静态的成员变量数据是在每个对象中都会维护一份数据的,三个线程对象就会有三份。解决方案:把num票数共享出来给三个线程对象使用。使用static修饰。问题2: 出现了线程安全问题 ?线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。 java线程同步机制的方式: 方式一:同步代码块 同步代码块的格式: synchronized(锁对象){ 需要被同步的代码... }同步代码块要注意事项: 1. 任意的一个对象都可以做为锁对象。 2. 在同步代码块中调用了sleep方法并不是释放锁对象的。 3. 只有真正存在线程安全问题的时候才使用同步代码块,否则会降低效率的。 4. 多线程操作的锁 对象必须是 唯一共享的。否则无效。
synchronized (new Object()) { } 无效
synchronized ("锁") { } 有效,
"锁"被创建后,不会再被创建了。
5. 一个线程在同步代码块中sleep了,并不会释放锁对象。
6. 如果不存在着线程安全问题,千万不要使用同步代码块,因为会降低效率。
出现线程安全问题的根本原因: 1. 存在两个或者两个以上 的线程对象,而且线程之间共享着一个资源。 2. 有多个语句(两句及以上)操作了共享资源。(执行到一半,cpu执行权被抢走) */class SaleTicket extends Thread{ static int num = 50;//票数 非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的。 static Object o = new Object(); public SaleTicket(String name) { super(name); } @Override public void run() { while(true){ //同步代码块 synchronized ("锁") { if(num>0){ System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } num--; }else{ System.out.println("售罄了.."); break; } } } } } public class Demo4 { public static void main(String[] args) { //创建三个线程对象,模拟三个窗口 SaleTicket thread1 = new SaleTicket("窗口1"); SaleTicket thread2 = new SaleTicket("窗口2"); SaleTicket thread3 = new SaleTicket("窗口3"); //开启线程售票 thread1.start(); thread2.start(); thread3.start(); }}
如果采用第二种方式创建多线程,则不用static修饰num。因为只传了一个对象。
class SaleTicket implements Runnable{ int num = 50; // 票数 @Override public void run() { while(true){ synchronized ("锁") { if(num>0){ System.out.println(Thread.currentThread().getName()+"售出了第"+ num+"号票"); num--; }else{ System.out.println("售罄了.."); break; } } } }}public class Demo4 { public static void main(String[] args) { //创建了一个Runnable实现类的对象 SaleTicket saleTicket = new SaleTicket(); //创建三个线程对象模拟三个窗口 Thread thread1 = new Thread(saleTicket,"窗口1"); Thread thread2 = new Thread(saleTicket,"窗口2"); Thread thread3 = new Thread(saleTicket,"窗口3"); //开启线程售票 thread1.start(); thread2.start(); thread3.start(); }}
0 0
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程安全问题
- 线程同步---线程安全问题
- Servlet字符编码过滤器,实现图书信息的添加功能,避免产生文字乱码现象的产生
- 线程常用方法
- 2012年07月04日的日记
- 工作中常用的正则表达式
- java虚拟机笔记
- 线程安全问题
- 读《瓦尔登湖》后感
- 线程安全问题(二)
- LeetCode (10)Regular Expression Matching
- StartUML的基础的使用,用例图,序列图
- 深入浅出nodejs学习笔记--第六~八章 理解Buffer 网络编程 构建WEB应用
- 死锁
- vi编辑文件
- ABAP DOI详解(3)