转载

java并发编程学习之synchronize(一)

线程安全问题

在 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并发编程学习之synchronize(一)

为什么会不安全呢,在 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();
        }
    }

运行结果如下:

java并发编程学习之synchronize(一)

java并发编程学习之synchronize(一)

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

原文  https://segmentfault.com/a/1190000019654068
正文到此结束
Loading...