线程安全
2021-01-25 07:15
标签:com oid vat 自动 cal user 状态 final encoding 线程安全 标签:com oid vat 自动 cal user 状态 final encoding 原文地址:https://www.cnblogs.com/wuhao-0206/p/12862227.html1、线程安全:多线程单线程程序运行结果一致
线程不安全:多线程单线程程序运行结果不一致
2、导致线程安全问题原因
全局变量或者静态变量引起;
一般情况下,多个线程只读数据,不写数据,则线程是安全的;
若多个线程同时执行写操作,则容易导致线程不安全问题发生。
根本原因:
多个线程操作共享的数据
操作共享数据的线程代码有多条
多个线程对共享数据有写操作
3、线程安全演示
单线程情况:
package com.wuhao.thread;
/**
* 线程安全演示
*/
public class Ticket implements Runnable {
private Integer ticketNum = 100;//电影票张数
@Override
public void run() {
while (true){
if (ticketNum>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("线程"+name+"销售电影票:"+ticketNum--);
}
}
}
}
package com.wuhao.thread;
public class TicketSafeTest {
public static void main(String[] args) {
//1、创建电影票对象
Ticket ticket = new Ticket();
//2、创建Thread,执行电影票售卖
Thread thread = new Thread(ticket,"窗口一");
Thread thread1 = new Thread(ticket,"窗口二");
Thread thread2= new Thread(ticket,"窗口三");
thread.start();
thread1.start();
thread2.start();
}
}
"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=56766:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_safety\target\classes" com.wuhao.thread.TicketSafeTest
线程窗口二销售电影票:100
线程窗口三销售电影票:99
线程窗口一销售电影票:100
线程窗口三销售电影票:98
线程窗口二销售电影票:97
线程窗口一销售电影票:98
线程窗口二销售电影票:96
线程窗口一销售电影票:95
线程窗口三销售电影票:95
线程窗口三销售电影票:94
线程窗口二销售电影票:93
线程窗口一销售电影票:92
线程窗口一销售电影票:91
线程窗口二销售电影票:90
线程窗口三销售电影票:89
线程窗口一销售电影票:88
线程窗口三销售电影票:88
线程窗口二销售电影票:88
线程窗口一销售电影票:87
线程窗口二销售电影票:87
线程窗口三销售电影票:87
线程窗口一销售电影票:86
线程窗口二销售电影票:86
线程窗口三销售电影票:86
线程窗口一销售电影票:85
线程窗口三销售电影票:85
线程窗口二销售电影票:85
线程窗口一销售电影票:84
线程窗口二销售电影票:84
线程窗口三销售电影票:84
线程窗口一销售电影票:83
线程窗口二销售电影票:82
线程窗口三销售电影票:81
线程窗口二销售电影票:80
线程窗口三销售电影票:80
线程窗口一销售电影票:80
线程窗口三销售电影票:79
线程窗口一销售电影票:77
线程窗口二销售电影票:78
线程窗口一销售电影票:76
线程窗口三销售电影票:76
线程窗口二销售电影票:76
线程窗口二销售电影票:75
线程窗口三销售电影票:75
线程窗口一销售电影票:75
线程窗口三销售电影票:74
线程窗口一销售电影票:74
线程窗口二销售电影票:74
线程窗口二销售电影票:73
线程窗口三销售电影票:73
线程窗口一销售电影票:73
线程窗口三销售电影票:72
线程窗口二销售电影票:72
线程窗口一销售电影票:72
线程窗口三销售电影票:71
线程窗口一销售电影票:71
线程窗口二销售电影票:71
线程窗口二销售电影票:70
线程窗口一销售电影票:70
线程窗口三销售电影票:70
线程窗口二销售电影票:69
线程窗口三销售电影票:69
线程窗口一销售电影票:69
线程窗口一销售电影票:68
线程窗口三销售电影票:68
线程窗口二销售电影票:68
线程窗口一销售电影票:67
线程窗口二销售电影票:66
线程窗口三销售电影票:66
线程窗口三销售电影票:65
线程窗口二销售电影票:64
线程窗口一销售电影票:65
线程窗口二销售电影票:63
线程窗口一销售电影票:63
线程窗口三销售电影票:63
线程窗口二销售电影票:62
线程窗口三销售电影票:62
线程窗口一销售电影票:62
线程窗口一销售电影票:61
线程窗口三销售电影票:61
线程窗口二销售电影票:60
线程窗口一销售电影票:59
线程窗口二销售电影票:58
线程窗口三销售电影票:58
线程窗口一销售电影票:57
线程窗口二销售电影票:57
线程窗口三销售电影票:57
线程窗口二销售电影票:56
线程窗口三销售电影票:55
线程窗口一销售电影票:56
线程窗口三销售电影票:54
线程窗口一销售电影票:54
线程窗口二销售电影票:54
线程窗口一销售电影票:53
线程窗口三销售电影票:52
线程窗口二销售电影票:53
线程窗口二销售电影票:51
线程窗口一销售电影票:51
线程窗口三销售电影票:50
线程窗口一销售电影票:49
线程窗口三销售电影票:49
线程窗口二销售电影票:49
线程窗口一销售电影票:48
线程窗口二销售电影票:47
线程窗口三销售电影票:48
线程窗口二销售电影票:46
线程窗口一销售电影票:46
线程窗口三销售电影票:46
线程窗口一销售电影票:45
线程窗口二销售电影票:44
线程窗口三销售电影票:43
线程窗口三销售电影票:42
线程窗口一销售电影票:42
线程窗口二销售电影票:42
线程窗口二销售电影票:41
线程窗口一销售电影票:41
线程窗口三销售电影票:41
线程窗口三销售电影票:40
线程窗口一销售电影票:40
线程窗口二销售电影票:39
线程窗口一销售电影票:38
线程窗口三销售电影票:38
线程窗口二销售电影票:38
线程窗口一销售电影票:37
线程窗口二销售电影票:37
线程窗口三销售电影票:37
线程窗口二销售电影票:36
线程窗口三销售电影票:36
线程窗口一销售电影票:36
线程窗口三销售电影票:35
线程窗口二销售电影票:34
线程窗口一销售电影票:35
线程窗口一销售电影票:33
线程窗口三销售电影票:31
线程窗口二销售电影票:32
线程窗口一销售电影票:30
线程窗口三销售电影票:30
线程窗口二销售电影票:30
线程窗口三销售电影票:29
线程窗口二销售电影票:29
线程窗口一销售电影票:29
线程窗口一销售电影票:28
线程窗口二销售电影票:27
线程窗口三销售电影票:28
线程窗口一销售电影票:26
线程窗口二销售电影票:26
线程窗口三销售电影票:26
线程窗口一销售电影票:25
线程窗口三销售电影票:25
线程窗口二销售电影票:25
线程窗口一销售电影票:24
线程窗口三销售电影票:23
线程窗口二销售电影票:24
线程窗口一销售电影票:22
线程窗口二销售电影票:21
线程窗口三销售电影票:22
线程窗口一销售电影票:18
线程窗口二销售电影票:20
线程窗口三销售电影票:19
线程窗口三销售电影票:17
线程窗口二销售电影票:17
线程窗口一销售电影票:17
线程窗口二销售电影票:16
线程窗口一销售电影票:16
线程窗口三销售电影票:16
线程窗口二销售电影票:15
线程窗口三销售电影票:15
线程窗口一销售电影票:14
线程窗口一销售电影票:13
线程窗口二销售电影票:13
线程窗口三销售电影票:13
线程窗口一销售电影票:12
线程窗口二销售电影票:12
线程窗口三销售电影票:12
线程窗口二销售电影票:11
线程窗口三销售电影票:11
线程窗口一销售电影票:11
线程窗口三销售电影票:10
线程窗口二销售电影票:10
线程窗口一销售电影票:10
线程窗口三销售电影票:9
线程窗口一销售电影票:9
线程窗口二销售电影票:8
线程窗口三销售电影票:7
线程窗口一销售电影票:7
线程窗口二销售电影票:7
线程窗口三销售电影票:6
线程窗口一销售电影票:5
线程窗口二销售电影票:6
线程窗口三销售电影票:4
线程窗口一销售电影票:4
线程窗口二销售电影票:4
线程窗口一销售电影票:3
线程窗口三销售电影票:3
线程窗口二销售电影票:3
线程窗口三销售电影票:2
线程窗口二销售电影票:2
线程窗口一销售电影票:2
线程窗口一销售电影票:1
线程窗口二销售电影票:1
线程窗口三销售电影票:1
4、线程安全问题解决
同步代码块 synchronized
同步方法 synchronized
同步锁 ReentrantLock
特殊域变量 volatile
局部变量 ThreadLocal
阻塞队列 LinkedBlockingQuene
原子变量 Atomic*
同步代码块:
package com.wuhao.thread;
/**
* 线程安全演示
*/
public class Ticket implements Runnable {
private Integer ticketNum = 100;//电影票张数
private Object object = new Object();
@Override
public void run() {
while (true){
synchronized(object){
if (ticketNum>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("线程"+name+"销售电影票:"+ticketNum--);
}
}
}
}
}
package com.wuhao.thread;
public class TicketSafeTest {
public static void main(String[] args) {
//1、创建电影票对象
Ticket ticket = new Ticket();
//2、创建Thread,执行电影票售卖
Thread thread = new Thread(ticket,"窗口一");
Thread thread1 = new Thread(ticket,"窗口二");
Thread thread2= new Thread(ticket,"窗口三");
thread.start();
thread1.start();
thread2.start();
}
}
"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=56925:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_safety\target\classes" com.wuhao.thread.TicketSafeTest
线程窗口一销售电影票:100
线程窗口一销售电影票:99
线程窗口一销售电影票:98
线程窗口一销售电影票:97
线程窗口一销售电影票:96
线程窗口三销售电影票:95
线程窗口三销售电影票:94
线程窗口二销售电影票:93
线程窗口二销售电影票:92
线程窗口二销售电影票:91
线程窗口二销售电影票:90
线程窗口二销售电影票:89
线程窗口二销售电影票:88
线程窗口二销售电影票:87
线程窗口二销售电影票:86
线程窗口三销售电影票:85
线程窗口三销售电影票:84
线程窗口三销售电影票:83
线程窗口三销售电影票:82
线程窗口三销售电影票:81
线程窗口三销售电影票:80
线程窗口三销售电影票:79
线程窗口三销售电影票:78
线程窗口三销售电影票:77
线程窗口三销售电影票:76
线程窗口三销售电影票:75
线程窗口三销售电影票:74
线程窗口三销售电影票:73
线程窗口三销售电影票:72
线程窗口三销售电影票:71
线程窗口三销售电影票:70
线程窗口三销售电影票:69
线程窗口三销售电影票:68
线程窗口三销售电影票:67
线程窗口三销售电影票:66
线程窗口三销售电影票:65
线程窗口三销售电影票:64
线程窗口三销售电影票:63
线程窗口三销售电影票:62
线程窗口三销售电影票:61
线程窗口三销售电影票:60
线程窗口三销售电影票:59
线程窗口三销售电影票:58
线程窗口三销售电影票:57
线程窗口三销售电影票:56
线程窗口三销售电影票:55
线程窗口三销售电影票:54
线程窗口三销售电影票:53
线程窗口三销售电影票:52
线程窗口三销售电影票:51
线程窗口三销售电影票:50
线程窗口三销售电影票:49
线程窗口三销售电影票:48
线程窗口三销售电影票:47
线程窗口三销售电影票:46
线程窗口三销售电影票:45
线程窗口三销售电影票:44
线程窗口三销售电影票:43
线程窗口三销售电影票:42
线程窗口三销售电影票:41
线程窗口一销售电影票:40
线程窗口一销售电影票:39
线程窗口一销售电影票:38
线程窗口一销售电影票:37
线程窗口一销售电影票:36
线程窗口一销售电影票:35
线程窗口一销售电影票:34
线程窗口一销售电影票:33
线程窗口一销售电影票:32
线程窗口一销售电影票:31
线程窗口一销售电影票:30
线程窗口一销售电影票:29
线程窗口一销售电影票:28
线程窗口一销售电影票:27
线程窗口一销售电影票:26
线程窗口一销售电影票:25
线程窗口一销售电影票:24
线程窗口一销售电影票:23
线程窗口一销售电影票:22
线程窗口一销售电影票:21
线程窗口一销售电影票:20
线程窗口一销售电影票:19
线程窗口一销售电影票:18
线程窗口一销售电影票:17
线程窗口一销售电影票:16
线程窗口一销售电影票:15
线程窗口一销售电影票:14
线程窗口一销售电影票:13
线程窗口一销售电影票:12
线程窗口一销售电影票:11
线程窗口一销售电影票:10
线程窗口一销售电影票:9
线程窗口一销售电影票:8
线程窗口一销售电影票:7
线程窗口一销售电影票:6
线程窗口一销售电影票:5
线程窗口一销售电影票:4
线程窗口一销售电影票:3
线程窗口一销售电影票:2
线程窗口一销售电影票:1
同步方法:
package com.wuhao.thread;
/**
* 线程安全演示
*/
public class Ticket implements Runnable {
private Integer ticketNum = 100;//电影票张数
private Object object = new Object();
@Override
public void run() {
while (true){
saleTicket();
}
}
private synchronized void saleTicket(){
if (ticketNum>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("线程"+name+"销售电影票:"+ticketNum--);
}
}
}
package com.wuhao.thread;
public class TicketSafeTest {
public static void main(String[] args) {
//1、创建电影票对象
Ticket ticket = new Ticket();
//2、创建Thread,执行电影票售卖
Thread thread = new Thread(ticket,"窗口一");
Thread thread1 = new Thread(ticket,"窗口二");
Thread thread2= new Thread(ticket,"窗口三");
thread.start();
thread1.start();
thread2.start();
}
}
"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=56973:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_safety\target\classes" com.wuhao.thread.TicketSafeTest
线程窗口二销售电影票:100
线程窗口二销售电影票:99
线程窗口二销售电影票:98
线程窗口二销售电影票:97
线程窗口二销售电影票:96
线程窗口二销售电影票:95
线程窗口二销售电影票:94
线程窗口二销售电影票:93
线程窗口二销售电影票:92
线程窗口二销售电影票:91
线程窗口二销售电影票:90
线程窗口二销售电影票:89
线程窗口二销售电影票:88
线程窗口二销售电影票:87
线程窗口二销售电影票:86
线程窗口二销售电影票:85
线程窗口二销售电影票:84
线程窗口二销售电影票:83
线程窗口二销售电影票:82
线程窗口二销售电影票:81
线程窗口二销售电影票:80
线程窗口二销售电影票:79
线程窗口二销售电影票:78
线程窗口二销售电影票:77
线程窗口二销售电影票:76
线程窗口二销售电影票:75
线程窗口二销售电影票:74
线程窗口二销售电影票:73
线程窗口一销售电影票:72
线程窗口一销售电影票:71
线程窗口一销售电影票:70
线程窗口一销售电影票:69
线程窗口三销售电影票:68
线程窗口三销售电影票:67
线程窗口三销售电影票:66
线程窗口三销售电影票:65
线程窗口三销售电影票:64
线程窗口一销售电影票:63
线程窗口一销售电影票:62
线程窗口一销售电影票:61
线程窗口一销售电影票:60
线程窗口一销售电影票:59
线程窗口一销售电影票:58
线程窗口一销售电影票:57
线程窗口一销售电影票:56
线程窗口二销售电影票:55
线程窗口一销售电影票:54
线程窗口一销售电影票:53
线程窗口一销售电影票:52
线程窗口一销售电影票:51
线程窗口一销售电影票:50
线程窗口一销售电影票:49
线程窗口三销售电影票:48
线程窗口三销售电影票:47
线程窗口三销售电影票:46
线程窗口三销售电影票:45
线程窗口三销售电影票:44
线程窗口一销售电影票:43
线程窗口一销售电影票:42
线程窗口一销售电影票:41
线程窗口二销售电影票:40
线程窗口一销售电影票:39
线程窗口一销售电影票:38
线程窗口一销售电影票:37
线程窗口一销售电影票:36
线程窗口三销售电影票:35
线程窗口一销售电影票:34
线程窗口一销售电影票:33
线程窗口二销售电影票:32
线程窗口一销售电影票:31
线程窗口一销售电影票:30
线程窗口三销售电影票:29
线程窗口三销售电影票:28
线程窗口三销售电影票:27
线程窗口三销售电影票:26
线程窗口一销售电影票:25
线程窗口二销售电影票:24
线程窗口二销售电影票:23
线程窗口一销售电影票:22
线程窗口一销售电影票:21
线程窗口一销售电影票:20
线程窗口一销售电影票:19
线程窗口三销售电影票:18
线程窗口三销售电影票:17
线程窗口三销售电影票:16
线程窗口三销售电影票:15
线程窗口三销售电影票:14
线程窗口一销售电影票:13
线程窗口二销售电影票:12
线程窗口二销售电影票:11
线程窗口二销售电影票:10
线程窗口二销售电影票:9
线程窗口二销售电影票:8
线程窗口二销售电影票:7
线程窗口一销售电影票:6
线程窗口一销售电影票:5
线程窗口三销售电影票:4
线程窗口一销售电影票:3
线程窗口一销售电影票:2
线程窗口一销售电影票:1
同步锁:
公平锁:各个线程有公平竞争锁的机会
独占锁:非公平锁,不是所有线程都有获得锁的机会
重入锁:线程再次请求锁的时候就能获得锁,则成锁为重入锁
注意:使用同步锁的时候,加锁必须伴随解锁,不然容易发生死锁,解锁过程用try代码块finally里书写
package com.wuhao.thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 线程安全演示
*/
public class Ticket implements Runnable {
private Integer ticketNum = 100;//电影票张数
private Object object = new Object();
private Lock lock = new ReentrantLock(true);//参数:是否为公平锁,true则为公平锁,公平锁意味着各个线程都有竞争锁的权利,false则是非公平锁,即为独占锁。
@Override
public void run() {
while (true){
lock.lock();//lock加锁
try {
if (ticketNum>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("线程"+name+"销售电影票:"+ticketNum--);
}
}finally {
lock.unlock();//解锁
}
}
}
private synchronized void saleTicket(){
}
}
package com.wuhao.thread;
public class TicketSafeTest {
public static void main(String[] args) {
//1、创建电影票对象
Ticket ticket = new Ticket();
//2、创建Thread,执行电影票售卖
Thread thread = new Thread(ticket,"窗口一");
Thread thread1 = new Thread(ticket,"窗口二");
Thread thread2= new Thread(ticket,"窗口三");
thread.start();
thread1.start();
thread2.start();
}
}
"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=58855:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_safety\target\classes" com.wuhao.thread.TicketSafeTest
线程窗口二销售电影票:100
线程窗口三销售电影票:99
线程窗口一销售电影票:98
线程窗口二销售电影票:97
线程窗口三销售电影票:96
线程窗口一销售电影票:95
线程窗口二销售电影票:94
线程窗口三销售电影票:93
线程窗口一销售电影票:92
线程窗口二销售电影票:91
线程窗口三销售电影票:90
线程窗口一销售电影票:89
线程窗口二销售电影票:88
线程窗口三销售电影票:87
线程窗口一销售电影票:86
线程窗口二销售电影票:85
线程窗口三销售电影票:84
线程窗口一销售电影票:83
线程窗口二销售电影票:82
线程窗口三销售电影票:81
线程窗口一销售电影票:80
线程窗口二销售电影票:79
线程窗口三销售电影票:78
线程窗口一销售电影票:77
线程窗口二销售电影票:76
线程窗口三销售电影票:75
线程窗口一销售电影票:74
线程窗口二销售电影票:73
线程窗口三销售电影票:72
线程窗口一销售电影票:71
线程窗口二销售电影票:70
线程窗口三销售电影票:69
线程窗口一销售电影票:68
线程窗口二销售电影票:67
线程窗口三销售电影票:66
线程窗口一销售电影票:65
线程窗口二销售电影票:64
线程窗口三销售电影票:63
线程窗口一销售电影票:62
线程窗口二销售电影票:61
线程窗口三销售电影票:60
线程窗口一销售电影票:59
线程窗口二销售电影票:58
线程窗口三销售电影票:57
线程窗口一销售电影票:56
线程窗口二销售电影票:55
线程窗口三销售电影票:54
线程窗口一销售电影票:53
线程窗口二销售电影票:52
线程窗口三销售电影票:51
线程窗口一销售电影票:50
线程窗口二销售电影票:49
线程窗口三销售电影票:48
线程窗口一销售电影票:47
线程窗口二销售电影票:46
线程窗口三销售电影票:45
线程窗口一销售电影票:44
线程窗口二销售电影票:43
线程窗口三销售电影票:42
线程窗口一销售电影票:41
线程窗口二销售电影票:40
线程窗口三销售电影票:39
线程窗口一销售电影票:38
线程窗口二销售电影票:37
线程窗口三销售电影票:36
线程窗口一销售电影票:35
线程窗口二销售电影票:34
线程窗口三销售电影票:33
线程窗口一销售电影票:32
线程窗口二销售电影票:31
线程窗口三销售电影票:30
线程窗口一销售电影票:29
线程窗口二销售电影票:28
线程窗口三销售电影票:27
线程窗口一销售电影票:26
线程窗口二销售电影票:25
线程窗口三销售电影票:24
线程窗口一销售电影票:23
线程窗口二销售电影票:22
线程窗口三销售电影票:21
线程窗口一销售电影票:20
线程窗口二销售电影票:19
线程窗口三销售电影票:18
线程窗口一销售电影票:17
线程窗口二销售电影票:16
线程窗口三销售电影票:15
线程窗口一销售电影票:14
线程窗口二销售电影票:13
线程窗口三销售电影票:12
线程窗口一销售电影票:11
线程窗口二销售电影票:10
线程窗口三销售电影票:9
线程窗口一销售电影票:8
线程窗口二销售电影票:7
线程窗口三销售电影票:6
线程窗口一销售电影票:5
线程窗口二销售电影票:4
线程窗口三销售电影票:3
线程窗口一销售电影票:2
线程窗口二销售电影票:1
总结:
synchronized是java内置关键字,在jvm层面,lock是个java类
synchronized无法判断是否获取锁的状态,lock可以判断是否获得锁
synchronized会自动释放锁,lock必须在finally代码块里释放锁,unlock()方法释放锁,否则容易造成死锁
synchronized的线程1和2,如果1获得锁,则2线程等待,如果线程1阻塞,线程2则一直等待,而Lock锁则不会,如果尝试获取不到锁,线程可以不用一直等待就结束
synchronized锁可重入,不可中断,非公平,而Lock锁可重入,可中断,可公平
Lock锁适合大量同步的代码同步问题,synchronized锁适合代码量少的同步
上一篇:算法模块总结