线程安全
程序员文章站
2022-05-14 10:21:35
1. 什么叫线程安全? 多线程对共享资源进行写的操作,受到其他线程的干扰,导致数据偶问题,这种现象叫做线程安全问题。 运行结果: 线程安全解决的办法: 使用多线程之间同步synchronized或使用锁(lock)。 为什么使用线程同步或使用锁能解决线程安全问题呢? 将可能发生线程安全的代码,在同一 ......
1. 什么叫线程安全?
多线程对共享资源进行写的操作,受到其他线程的干扰,导致数据偶问题,这种现象叫做线程安全问题。
package com.cn.test.thread; public class trainthread implements runnable { /** * 两个线程进行售票100张 */ private int trainticket = 100; @override public void run() { while (trainticket > 0) { try { thread.sleep(10); } catch (interruptedexception e) { e.printstacktrace(); } // 进行售票 system.out.println(thread.currentthread().getname() + "开始售票:" + (100 - trainticket + 1) + "张"); trainticket--; } } public static void main(string[] args) { trainthread train = new trainthread(); thread t1 = new thread(train,"窗口1"); thread t2 = new thread(train,"窗口2"); t1.start(); t2.start(); } }
运行结果:
窗口1开始售票:1张 窗口2开始售票:1张 窗口1开始售票:3张 窗口2开始售票:3张 窗口1开始售票:5张 窗口2开始售票:5张 窗口1开始售票:7张 窗口2开始售票:7张 窗口2开始售票:9张 窗口1开始售票:9张 窗口2开始售票:11张 窗口1开始售票:12张 窗口2开始售票:13张 窗口1开始售票:14张 窗口2开始售票:15张 窗口1开始售票:16张 窗口2开始售票:17张 窗口1开始售票:18张 窗口2开始售票:19张 窗口1开始售票:20张 窗口2开始售票:21张 窗口1开始售票:22张 窗口2开始售票:23张 窗口1开始售票:24张 窗口2开始售票:25张 窗口1开始售票:26张 窗口2开始售票:27张 窗口1开始售票:28张 窗口2开始售票:29张 窗口1开始售票:30张 窗口2开始售票:31张 窗口1开始售票:32张 窗口2开始售票:33张 窗口1开始售票:34张 窗口2开始售票:35张 窗口1开始售票:36张 窗口2开始售票:37张 窗口1开始售票:38张 窗口2开始售票:39张 窗口1开始售票:40张 窗口2开始售票:41张 窗口1开始售票:42张 窗口2开始售票:43张 窗口1开始售票:44张 窗口2开始售票:45张 窗口1开始售票:46张 窗口2开始售票:47张 窗口1开始售票:48张 窗口2开始售票:49张 窗口1开始售票:50张 窗口2开始售票:51张 窗口1开始售票:52张 窗口2开始售票:53张 窗口1开始售票:54张 窗口2开始售票:55张 窗口1开始售票:56张 窗口2开始售票:57张 窗口1开始售票:58张 窗口2开始售票:59张 窗口1开始售票:60张 窗口2开始售票:61张 窗口1开始售票:62张 窗口2开始售票:63张 窗口1开始售票:64张 窗口2开始售票:65张 窗口1开始售票:66张 窗口2开始售票:67张 窗口1开始售票:68张 窗口2开始售票:69张 窗口1开始售票:70张 窗口2开始售票:71张 窗口1开始售票:72张 窗口2开始售票:73张 窗口1开始售票:74张 窗口2开始售票:75张 窗口1开始售票:76张 窗口2开始售票:77张 窗口1开始售票:78张 窗口2开始售票:79张 窗口1开始售票:80张 窗口2开始售票:81张 窗口1开始售票:82张 窗口2开始售票:83张 窗口1开始售票:84张 窗口2开始售票:85张 窗口1开始售票:86张 窗口2开始售票:87张 窗口1开始售票:88张 窗口2开始售票:89张 窗口1开始售票:90张 窗口2开始售票:91张 窗口1开始售票:92张 窗口2开始售票:93张 窗口1开始售票:94张 窗口2开始售票:95张 窗口1开始售票:96张 窗口2开始售票:97张 窗口1开始售票:98张 窗口2开始售票:99张 窗口1开始售票:100张 窗口2开始售票:101张
线程安全解决的办法:
使用多线程之间同步synchronized或使用锁(lock)。
为什么使用线程同步或使用锁能解决线程安全问题呢?
将可能发生线程安全的代码,在同一时刻只有一个线程对此进行操作,代码执行完毕之后释放锁之后才让其他线程并发执行,这样就会解决线程安全的问题。
什么是线程同步?
多个线程共享同一个资源,不会受到其他线程的干扰。
解决办法1:
同步代码块。 将可能发生线程安全的代码用同步代码块包裹起来。
synchronized(同一个数据) {
可能会发生线程冲突问题
}
同步代码块需要传递的对象(锁对象):就是锁住这个对象,表示这个对象正在为我服务,其他人不能用(非synchronized代码块、方法除外)。
while (trainticket > 0) {
try {
thread.sleep(50);
} catch (interruptedexception e) {
e.printstacktrace();
}
synchronized (obj) {
// 进行售票
if (trainticket > 0) {
system.out.println(thread.currentthread().getname() + "开始售票:" + (100 - trainticket + 1) + "张");
trainticket--;
}
}
}
解决办法2:
同步函数,在发生线程安全的函数中加入sychnorized关键字。
静态同步函数:
方法上加上static关键字,使用synchronized 关键字修饰 或者使用类.class文件。静态的同步函数使用的锁是 该函数所属字节码文件对象可以用 getclass方法获取,也可以用当前 类名.class 表示。
死锁:
同步中嵌套同步,导致锁无法释放
package com.cn.test.thread; public class testdeadthread implements runnable { private boolean flag = true; private static int traincount = 100; private object mutex = new object(); @override public void run() { if (flag) { while(true) { synchronized (mutex) { sale(); } } } else { while (true) { sale(); } } } private synchronized void sale() { synchronized (mutex) { if (traincount > 0) { try { thread.sleep(40); } catch (exception e) { } system.out.println(thread.currentthread().getname() + ",出售 第" + (100 - traincount + 1) + "张票."); traincount--; } } } public static void main(string[] args) throws interruptedexception { testdeadthread test1 = new testdeadthread(); thread t1 = new thread(test1,"thread-1"); thread t2 = new thread(test1,"thread-2"); t1.start(); thread.sleep(40); test1.flag = false; t2.start(); } }
运行结果:
thread-1,出售 第1张票. thread-1,出售 第2张票. thread-1,出售 第3张票. thread-1,出售 第4张票. thread-1,出售 第5张票. thread-1,出售 第6张票. thread-1,出售 第7张票. thread-1,出售 第8张票. thread-1,出售 第9张票. thread-1,出售 第10张票. thread-1,出售 第11张票. thread-1,出售 第12张票. thread-1,出售 第13张票. thread-1,出售 第14张票. thread-1,出售 第15张票. thread-1,出售 第16张票. thread-1,出售 第17张票. thread-1,出售 第18张票. thread-1,出售 第19张票. thread-1,出售 第20张票. thread-1,出售 第21张票. thread-1,出售 第22张票. thread-1,出售 第23张票. thread-1,出售 第24张票. thread-1,出售 第25张票.