多线程——安全问题
来源:互联网 发布:陈欣怡药检呈阳性知乎 编辑:程序博客网 时间:2024/06/07 20:26
多线程运行可能出现安全问题
以买票程序为例,共有100张票,四个窗口同时买票。
class Ticket implements Runnable{private int tick = 100;public void run(){while(true){if(tick > 0){try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName() + " sale.." + tick--);}}}}public class Example1 {public static void main(String[] args){Ticket t = new Ticket();Thread t1 = new Thread(t);Thread t2 = new Thread(t);Thread t3 = new Thread(t);Thread t4 = new Thread(t);t1.start();t2.start();t3.start();t4.start();}}
通过分析,发现打印出0,-1,-2等错票。
多线程的运行出现了安全问题。
造成这种结果的可能原因:
当tick = 1的时候,0线程进来,执行sleep方法,进入睡眠状态。1线程进来,也进入睡眠。2线程进来,进入睡眠。3线程进来,执行输出语句,tick--变成0.这时1线程醒来直接执行输出语句,不需要判断,因为之前已经判断过。输出0。2线程也醒了,输出-1.于是就出现了输出负数的情况。
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误
解决办法:
对多条操作共享数据的语句,让一个线程都执行完。在执行过程中,其他线程不可 以参与执行
Java对于多线程的安全问题提供了专业的解决方式:
同步代码块
Synchronized(对象)
{
需要同步的代码 //哪些语句在操作共享数据,哪些代码就需要同步
}
对象如同锁,持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取CPU的执行权,也进不去。
对象有一个标志值,用来标志锁是打开的还是锁上的。当一个线程到来时,首先判断锁是否为开,如果是,则进入,并把锁锁上,其他线程就无法进来了。该线程执行完之后,离开,并把锁置为打开状态,以便其他线程进入。如果锁是锁上的,则进不去。
加锁后的Ticket函数为:
class Ticket implements Runnable{private int tick = 100;Object obj = new Object();public void run(){while(true){synchronized(obj){if(tick > 0){try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName() + " sale.." + tick--);}}}}}
同步的前提:
1.必须要有两个或两个以上的线程
2.必须是多个线程使用同一个锁
3.必须保证同步中只能有一个线程在运行
好处:解决了多线程的安全问题。
弊端:多线程需要判断锁,较为消耗资源。
- 多线程——安全问题
- Java——多线程安全问题
- Java基础——多线程的安全问题
- 黑马程序员——多线程中的安全问题 :
- Java——多线程存在的安全问题
- 黑马程序员—多线程安全问题(锁)
- Java_基础—多线程(线程安全问题)
- Java多线程技术初识——3. 线程安全问题
- 黑马程序员——Java多线程之线程安全问题
- (47)Java学习笔记——多线程 / 线程的安全问题
- java中多线程安全问题产生&解决方案——同步方法
- Java——生产者消费者中多线程安全问题
- 多线程安全问题
- 多线程安全问题
- 多线程安全问题
- 多线程安全问题
- 多线程安全问题。
- 多线程安全问题
- leetcode-148 Sort List
- [Android]实现带显示密码按钮的EditText(无内存泄露)
- java中JVM加载类的时机
- [黑马程序员]8 JAVA基础-IO流
- Java程序如何生成Jar、exe及安装文件
- 多线程——安全问题
- PowerDesigner 反向 PostgreSQL 时 Unable to list the columns. SQLSTATE =22003 的解决方法
- java文件读写操作大全
- puppet 安装及应用
- 4.25
- TPL Part3 -- 数据共享
- 第七周 课后实践:项目一——图形用户界面(GUI)应用程序开发初体验
- 阿里巴巴前端面试题:三列布局知多少?
- Visual Studio 2013 编写汇编代码