线程安全
Posted wuhao-0206
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程安全相关的知识,希望对你有一定的参考价值。
1、线程安全:多线程单线程程序运行结果一致 线程不安全:多线程单线程程序运行结果不一致 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 FilesJavajdk1.8.0_131injava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5libidea_rt.jar=56766:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_131jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_131jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_131jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_131jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_131jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_131jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_131jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_131jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_131jrelibext ashorn.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_131jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_131jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_131jrelibjce.jar;C:Program FilesJavajdk1.8.0_131jrelibjfr.jar;C:Program FilesJavajdk1.8.0_131jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_131jrelibjsse.jar;C:Program FilesJavajdk1.8.0_131jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_131jrelibplugin.jar;C:Program FilesJavajdk1.8.0_131jrelib esources.jar;C:Program FilesJavajdk1.8.0_131jrelib t.jar;C:UsersAdministratorIdeaProjectsmultiThread hread_safety argetclasses" 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 FilesJavajdk1.8.0_131injava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5libidea_rt.jar=56925:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_131jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_131jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_131jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_131jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_131jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_131jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_131jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_131jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_131jrelibext ashorn.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_131jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_131jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_131jrelibjce.jar;C:Program FilesJavajdk1.8.0_131jrelibjfr.jar;C:Program FilesJavajdk1.8.0_131jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_131jrelibjsse.jar;C:Program FilesJavajdk1.8.0_131jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_131jrelibplugin.jar;C:Program FilesJavajdk1.8.0_131jrelib esources.jar;C:Program FilesJavajdk1.8.0_131jrelib t.jar;C:UsersAdministratorIdeaProjectsmultiThread hread_safety argetclasses" 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 FilesJavajdk1.8.0_131injava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5libidea_rt.jar=56973:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_131jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_131jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_131jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_131jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_131jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_131jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_131jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_131jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_131jrelibext ashorn.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_131jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_131jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_131jrelibjce.jar;C:Program FilesJavajdk1.8.0_131jrelibjfr.jar;C:Program FilesJavajdk1.8.0_131jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_131jrelibjsse.jar;C:Program FilesJavajdk1.8.0_131jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_131jrelibplugin.jar;C:Program FilesJavajdk1.8.0_131jrelib esources.jar;C:Program FilesJavajdk1.8.0_131jrelib t.jar;C:UsersAdministratorIdeaProjectsmultiThread hread_safety argetclasses" 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 FilesJavajdk1.8.0_131injava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5libidea_rt.jar=58855:C:Program FilesJetBrainsIntelliJ IDEA 2018.2.5in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_131jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_131jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_131jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_131jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_131jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_131jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_131jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_131jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_131jrelibext ashorn.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_131jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_131jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_131jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_131jrelibjce.jar;C:Program FilesJavajdk1.8.0_131jrelibjfr.jar;C:Program FilesJavajdk1.8.0_131jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_131jrelibjsse.jar;C:Program FilesJavajdk1.8.0_131jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_131jrelibplugin.jar;C:Program FilesJavajdk1.8.0_131jrelib esources.jar;C:Program FilesJavajdk1.8.0_131jrelib t.jar;C:UsersAdministratorIdeaProjectsmultiThread hread_safety argetclasses" 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锁适合代码量少的同步
以上是关于线程安全的主要内容,如果未能解决你的问题,请参考以下文章
HashMap 和 ConcurrentHashMap 的区别
newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段