线程安全问题

在java并发编程学习之基础概念提到,多线程的劣势之一,有个线程安全问题,现在看看下面的例子。

public class NotSafeDemo {    private int num = 0;     public void add(int value) {        try {            num = num + value;            Thread.sleep(100);            System.out.println("num:" + num);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        NotSafeDemo synchronizeDemo = new NotSafeDemo();        AddThread1 addThread1 = new AddThread1(synchronizeDemo);        AddThread2 addThread2 = new AddThread2(synchronizeDemo);        addThread1.start();        addThread2.start();    }}class AddThread1 extends Thread {    NotSafeDemo synchronizeDemo;    public AddThread1(NotSafeDemo synchronizeDemo) {        this.synchronizeDemo = synchronizeDemo;    }    @Override    public void run() {        synchronizeDemo.add(1);    }}class AddThread2 extends Thread {    NotSafeDemo synchronizeDemo;    public AddThread2(NotSafeDemo synchronizeDemo) {        this.synchronizeDemo = synchronizeDemo;    }    @Override    public void run() {        synchronizeDemo.add(2);    }}

运行结果如下:

为什么会不安全呢,在java并发编程学习之基础概念提过,两个线程共享一个进程的资源,也就是说,num这个值,是共享的,在还没输出num的时候,已经被第二个线程,改成3,所以两次输出都是3。那么,该怎么解决呢,很简单,在方法前加个同步锁synchronized。

synchronized public void add(int value) {        try {            int temp = num;            num = num + value;            Thread.sleep(100);            System.out.println(value + "+" + temp + "=" + num);        } catch (InterruptedException e) {            e.printStackTrace();        }    }

运行结果如下:

有两种情况,是因为看谁先抢占锁,但是输出的算法结果是正确的。