多线程的安全性问题
来源:互联网 发布:php删除数组指定元素 编辑:程序博客网 时间:2024/04/30 11:18
上一节中,虽然我们已经完成了卖票程序,但是其实隐藏了一个非常严重的安全问题,我们看代码这段代码:
class Ticket implements Runnable{ private int tick=100; public void run(){ while (true){ if(tick>0){ System.out.println(Thread.currentThread().getName()+"....sale"+tick--); } } }}
当票剩余一张时,在我们的if(tick>0)的时候,我们的0线程进入,这时候0线程进入暂时状态,1线程进入,因为此时tick还未变化, 如果这个时候1线程也进入暂时状态。这个时候就会出现卖出0张票和-1张票的情况。
我们可以模拟下这个情况:
class Ticket implements Runnable{ private int tick=100; public void run(){ while (true){ if(tick>0){ try{ Thread.sleep(100); }catch(Exception e){ } } System.out.println(Thread.currentThread().getName()+"....sale"+tick--); } } }}
此时我们运行发现:
多线程的运行出了安全问题。
当多个线程在操作同一个共享数据时, 一个线程对多余语句只执行了一部分,还没执行完,另一个线程参与进来执行,导致共享数据的错误。
解决办法: 对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。
java对于多线的安全问题提供了专业的解决方式, 就是同步代码块。
synchronized(对象){ 需要同步的代码块}
改正后的代码
class Ticket implements Runnable { private int tick = 100; Object o=new Object(); //锁 public void run() { while (true) { synchronized (o) { if (tick > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "....sale" + tick--); } } } }}
原理,锁对象具有一个标志位,当线程进来时,将标志位置成0,其他线程进不来,出去后,标志位重新置成1,其他线程就可以进来了。
对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取了cup的执行权,也进不去, 因为没有获取锁。
同步的前提:
1.必须要有两个或者两个以上的线程。
2.必须是多个线程使用同一个锁。
必须保证同步中只有一个线程在运行。
好处:解决了多线程的安全问题;
弊端:多个线程需要判断锁,较为消耗资源。
同步函数:
我们可以让函数具有同步的功能,只需要在定义函数的时候加上synchronized,此时该函数就具备同步代码块的功能,线程安全。
public synchronized void add (int n){ sum=sum+n;}
同步函数用的是哪一个锁呢?
函数需要被对象调用,那么函数都有一个所属对象引用,就是this。所以同步函数使用的锁是this。
- 多线程的安全性问题
- epoll的多线程安全性问题
- Java多线程之i++的安全性问题
- 多线程fork的安全性
- 函数的多线程安全性
- servlet 多线程安全性问题分析
- Servlet多线程安全性有关问题
- 多线程访问数据库的安全性
- 多线程下单例模式的安全性
- 【Java多线程】线程的安全性
- 手机的安全性问题
- Servlet的安全性问题
- SQLite安全性的问题
- memcache 的安全性问题
- 深入研究Servlet多线程安全性问题
- 多线程安全性
- 多线程安全性
- 多线程编程 深入理解DCL的安全性
- Add to List 611. Valid Triangle Number
- (菜汪学jvm)java内存区域简介
- java中使用$.ajax创建下拉选项
- 比小强还小强的生物
- 1022D进制转换(进制转换)
- 多线程的安全性问题
- ios-Swift中的闭包
- 控制前置0的输出
- mysql设置ip连接
- POJ1961Period
- vue02
- 199. Binary Tree Right Side View
- WEB_02_CSS_第一讲
- Unity3d键盘控制角色移动