线程安全

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 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锁适合代码量少的同步

 

posted @ 2020-05-10 09:36  久别重逢  阅读(102)  评论(0编辑  收藏  举报