在 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(); } }
运行结果如下:
有两种情况,是因为看谁先抢占锁,但是输出的算法结果是正确的。