如何解决多线程不安全
2017-08-21 16:45
204 查看
如何解决多线程不安全
比如买票,会出现一票多求,负票等问题 解决; java提供了一个同步机制(同步锁):synchronized :包装其中的多条语句 例: synchronized(对象){ 多条语句对共享语句进行操作 } 对象:需要使用同一个对象,封装到外面 注意:任意对象,但必须创建,也必须存在
线程安全的检测条件:
1)看我们当前的环境是否属于多线程程序
2)当前的多线程程序中是否有共享数据
3)是否多条语句对共性数据进行操作
需求:
模拟电影院售票案例,现有100张票,三家影院同时出售,卖出每张票中间会有100毫秒的延迟
代码:
public class SellTickets implements Runnable {
//定义票数 private int tickets = 1; Demo d = new Demo(); @Override public void run() { while(tickets<=100){ //同步锁 synchronized(d){ if(tickets<=100){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+"正在出售第"+(tickets++)+"张票"); } } } }
}
class Demo{}
public static void main(String[] args) {
SellTickets st = new SellTickets();
//创建线程对象 Thread th1 = new Thread(st, "窗口一"); Thread th2 = new Thread(st, "窗口二"); Thread th3 = new Thread(st, "窗口三"); //启动线程 th1.start(); th2.start(); th3.start(); }
结果:
窗口一:正在出售第1张票
窗口一:正在出售第2张票
窗口一:正在出售第3张票
窗口三:正在出售第4张票
窗口三:正在出售第5张票
窗口二:正在出售第6张票
窗口二:正在出售第7张票
窗口三:正在出售第8张票
窗口三:正在出售第9张票
窗口一:正在出售第10张票
窗口一:正在出售第11张票
窗口三:正在出售第12张票
窗口二:正在出售第13张票
窗口二:正在出售第14张票
窗口三:正在出售第15张票
窗口三:正在出售第16张票
窗口一:正在出售第17张票
窗口一:正在出售第18张票
窗口一:正在出售第19张票
窗口三:正在出售第20张票
窗口三:正在出售第21张票
窗口三:正在出售第22张票
窗口三:正在出售第23张票
窗口三:正在出售第24张票
窗口三:正在出售第25张票
窗口三:正在出售第26张票
窗口三:正在出售第27张票
窗口二:正在出售第28张票
窗口二:正在出售第29张票
窗口二:正在出售第30张票
窗口三:正在出售第31张票
窗口三:正在出售第32张票
窗口三:正在出售第33张票
窗口三:正在出售第34张票
窗口一:正在出售第35张票
窗口三:正在出售第36张票
窗口二:正在出售第37张票
窗口三:正在出售第38张票
窗口三:正在出售第39张票
窗口三:正在出售第40张票
窗口三:正在出售第41张票
窗口三:正在出售第42张票
窗口一:正在出售第43张票
窗口三:正在出售第44张票
窗口三:正在出售第45张票
窗口三:正在出售第46张票
窗口三:正在出售第47张票
窗口三:正在出售第48张票
窗口三:正在出售第49张票
窗口三:正在出售第50张票
窗口二:正在出售第51张票
窗口二:正在出售第52张票
窗口二:正在出售第53张票
窗口二:正在出售第54张票
窗口二:正在出售第55张票
窗口三:正在出售第56张票
窗口一:正在出售第57张票
窗口一:正在出售第58张票
窗口三:正在出售第59张票
窗口三:正在出售第60张票
窗口三:正在出售第61张票
窗口三:正在出售第62张票
窗口三:正在出售第63张票
窗口三:正在出售第64张票
窗口三:正在出售第65张票
窗口二:正在出售第66张票
窗口三:正在出售第67张票
窗口三:正在出售第68张票
窗口三:正在出售第69张票
窗口三:正在出售第70张票
窗口三:正在出售第71张票
窗口三:正在出售第72张票
窗口三:正在出售第73张票
窗口三:正在出售第74张票
窗口一:正在出售第75张票
窗口三:正在出售第76张票
窗口三:正在出售第77张票
窗口三:正在出售第78张票
窗口三:正在出售第79张票
窗口三:正在出售第80张票
窗口二:正在出售第81张票
窗口三:正在出售第82张票
窗口一:正在出售第83张票
窗口三:正在出售第84张票
窗口三:正在出售第85张票
窗口二:正在出售第86张票
窗口二:正在出售第87张票
窗口三:正在出售第88张票
窗口三:正在出售第89张票
窗口一:正在出售第90张票
窗口一:正在出售第91张票
窗口三:正在出售第92张票
窗口三:正在出售第93张票
窗口二:正在出售第94张票
窗口三:正在出售第95张票
窗口一:正在出售第96张票
窗口一:正在出售第97张票
窗口三:正在出售第98张票
窗口二:正在出售第99张票
窗口二:正在出售第100张票
使用同步机制解决了线程的安全问题,但是我们并没有看到具体的锁对象是谁,JDK5以后java提供了接口Lock,里面又提供了一些方法:
public void lock()获取锁
public void unlock():释放锁
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作 由于该Lock接口不能实例化,提供了子实现类:ReentrantLock
代码:
public class MyLock implements Runnable{ private int tickets = 1; //创建锁对象 Lock l = new ReentrantLock(); @Override public void run() { while(tickets <= 100){ l.lock(); if(tickets<=100){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+"正在出售第"+(tickets++)+"张票"); } l.unlock(); } }
}
public static void main(String[] args) {
MyLock ml = new MyLock();
//创建多线程对象 Thread th1 = new Thread(ml, "窗口一"); Thread th2 = new Thread(ml, "窗口二"); Thread th3 = new Thread(ml, "窗口三"); th1.start(); th2.start(); th3.start(); }
结果:
窗口一:正在出售第1张票
窗口二:正在出售第2张票
窗口二:正在出售第3张票
窗口二:正在出售第4张票
窗口二:正在出售第5张票
窗口二:正在出售第6张票
窗口二:正在出售第7张票
窗口二:正在出售第8张票
窗口二:正在出售第9张票
窗口二:正在出售第10张票
窗口二:正在出售第11张票
窗口三:正在出售第12张票
窗口一:正在出售第13张票
窗口二:正在出售第14张票
窗口三:正在出售第15张票
窗口一:正在出售第16张票
窗口二:正在出售第17张票
窗口二:正在出售第18张票
窗口二:正在出售第19张票
窗口三:正在出售第20张票
窗口三:正在出售第21张票
窗口三:正在出售第22张票
窗口一:正在出售第23张票
窗口二:正在出售第24张票
窗口二:正在出售第25张票
窗口二:正在出售第26张票
窗口二:正在出售第27张票
窗口二:正在出售第28张票
窗口二:正在出售第29张票
窗口二:正在出售第30张
4000
票
窗口三:正在出售第31张票
窗口三:正在出售第32张票
窗口一:正在出售第33张票
窗口二:正在出售第34张票
窗口三:正在出售第35张票
窗口一:正在出售第36张票
窗口二:正在出售第37张票
窗口二:正在出售第38张票
窗口二:正在出售第39张票
窗口二:正在出售第40张票
窗口二:正在出售第41张票
窗口二:正在出售第42张票
窗口二:正在出售第43张票
窗口二:正在出售第44张票
窗口二:正在出售第45张票
窗口二:正在出售第46张票
窗口二:正在出售第47张票
窗口三:正在出售第48张票
窗口三:正在出售第49张票
窗口三:正在出售第50张票
窗口三:正在出售第51张票
窗口三:正在出售第52张票
窗口一:正在出售第53张票
窗口二:正在出售第54张票
窗口二:正在出售第55张票
窗口二:正在出售第56张票
窗口三:正在出售第57张票
窗口三:正在出售第58张票
窗口一:正在出售第59张票
窗口二:正在出售第60张票
窗口二:正在出售第61张票
窗口二:正在出售第62张票
窗口二:正在出售第63张票
窗口二:正在出售第64张票
窗口二:正在出售第65张票
窗口二:正在出售第66张票
窗口二:正在出售第67张票
窗口二:正在出售第68张票
窗口二:正在出售第69张票
窗口二:正在出售第70张票
窗口三:正在出售第71张票
窗口一:正在出售第72张票
窗口二:正在出售第73张票
窗口二:正在出售第74张票
窗口二:正在出售第75张票
窗口二:正在出售第76张票
窗口二:正在出售第77张票
窗口二:正在出售第78张票
窗口二:正在出售第79张票
窗口二:正在出售第80张票
窗口二:正在出售第81张票
窗口二:正在出售第82张票
窗口二:正在出售第83张票
窗口二:正在出售第84张票
窗口二:正在出售第85张票
窗口二:正在出售第86张票
窗口二:正在出售第87张票
窗口二:正在出售第88张票
窗口二:正在出售第89张票
窗口二:正在出售第90张票
窗口二:正在出售第91张票
窗口二:正在出售第92张票
窗口二:正在出售第93张票
窗口二:正在出售第94张票
窗口二:正在出售第95张票
窗口二:正在出售第96张票
窗口二:正在出售第97张票
窗口三:正在出售第98张票
窗口一:正在出售第99张票
窗口二:正在出售第100张票
相关文章推荐
- java多线程的等待唤醒机制及如何解决同步过程中的安全问题
- 黑马程序员-(多线程)了解线程与如何解决线程同步到来的安全问题!(面试)
- selenium如何解决window安全验证问题
- 出于安全考虑,office outlook禁止对潜在不安全因素的附件访问,如何解决
- 多线程学习2,买火车票,并解决同步安全的问题
- c# winform下使用多线程时在线程里如何安全访问窗体控件InvokeRequired
- Linux 多线程应用中如何编写安全的信号处理函数
- 如何自建个人网盘,解决云端数据安全问题
- 如何确定多线程程序是否有安全问题
- java多线程安全问题的解决
- WEB应用如何解决安全退出问题
- servlet如何实现多线程安全??
- Linux 多线程应用中如何编写安全的信号处理函数
- Linux 多线程应用中如何编写安全的信号处理函数
- 基础篇_线程 第4集 多线程的安全问题--解决之道同步代码块
- 源代码加密软件如何解决文件流转过程中的安全问题
- 如何解决 Java 安全问题?
- 如何解决企业无线网络稳行与安全问题?
- 如何解决JApplet的安全问题?
- 黑马程序员——多线程——多线程概述,实现,控制与安全问题的解决