线程安全 - morris131/morris-book GitHub Wiki

##线程安全 线程安全即线程同步,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问。

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

线程安全问题都是由全局变量及静态变量引起的。

若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

存在竞争的线程不安全,不存在竞争的线程就是安全的

线程间不共享数据线程安全

package com.morris.ch1;

public class NoShareCountThread extends Thread {
    private int count = 5;

    public NoShareCountThread(String threadName) {
        super(threadName);
    }

    @Override
    public void run() {
        while (count > 0) {
            count--;
            System.out.println("Thread " + Thread.currentThread().getName() + " count:" + count);
        }
    }

    public static void main(String[] args) {
        NoShareCountThread a = new NoShareCountThread("A");
        NoShareCountThread b = new NoShareCountThread("B");
        NoShareCountThread c = new NoShareCountThread("C");
        a.start();
        b.start();
        c.start();
    }
}

运行结果如下:

Thread A count:4
Thread A count:3
Thread A count:2
Thread A count:1
Thread A count:0
Thread C count:4
Thread C count:3
Thread C count:2
Thread C count:1
Thread C count:0
Thread B count:4
Thread B count:3
Thread B count:2
Thread B count:1
Thread B count:0

线程共享数据线程不安全

package com.morris.ch1;

public class ShareAsyCountThread extends Thread {
    private int count = 5;

    @Override
    public void run() {
        count--;
        System.out.println("Thread " + Thread.currentThread().getName() + " count:" + count);
    }

    public static void main(String[] args) {
        ShareAsyCountThread thread = new ShareAsyCountThread();
        Thread a = new Thread(thread, "A");
        Thread b = new Thread(thread, "B");
        Thread c = new Thread(thread, "C");
        Thread d = new Thread(thread, "D");
        Thread e = new Thread(thread, "E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}

}

运行结果如下:

Thread A count:4
Thread B count:2
Thread C count:2
Thread D count:1
Thread E count:0

解决线程不安全问题

package com.morris.ch1;

public class ShareSynCountThread extends Thread {
    private int count = 5;

    @Override
    public synchronized void run() { // 在方法前增加synchronized即可解决线程不安全问题
        count--;
        System.out.println("Thread " + Thread.currentThread().getName() + " count:" + count);
    }

    public static void main(String[] args) {
        ShareSynCountThread thread = new ShareSynCountThread();
        Thread a = new Thread(thread, "A");
        Thread b = new Thread(thread, "B");
        Thread c = new Thread(thread, "C");
        Thread d = new Thread(thread, "D");
        Thread e = new Thread(thread, "E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}

运行结果如下:

Thread A count:4
Thread C count:3
Thread E count:2
Thread B count:1
Thread D count:0
⚠️ **GitHub.com Fallback** ⚠️