synchronized的使用

2018-11-15  本文已影响6人  jeffrey要努力

使用synchronized 修饰方法

public class TestSync extends Thread{
    private int position;
    public TestSync(int position){
        this.position = position;
    }
    @Override
    public void run() {
        super.run();
        try {
            doSomething(position);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void doSomething(int position) throws InterruptedException {
        Log.d("TestSync","doSomething start " + position);
        Thread.sleep(2000);
        Log.d("TestSync","doSomething end " + position);
    }
}

测试:生成三个TestSync对象,让他运行

for (int i = 0 ; i < 3 ;i ++){
                    TestSync testSync = new TestSync(i);
                    testSync.start();
}

结果: synchronized 不能锁同一个类的不同对象

 doSomething start 1
 doSomething start 2
 doSomething start 0
doSomething end 1
doSomething end 2
doSomething end 0

换成一个对象运行在不同的线程中运行呢

 TestSync testSync = new TestSync(0);
for (int i = 0 ; i < 3 ;i ++){
        new Thread(testSync).start();
 }

结果:一个完成后才能继续下一个,synchronized 成功锁住了对象

01-01 13:46:16.985 D/TestSync: doSomething start 0
01-01 13:46:18.986 D/TestSync: doSomething end 0
01-01 13:46:18.986  D/TestSync: doSomething start 0
01-01 13:46:20.986  D/TestSync: doSomething end 0
01-01 13:46:20.986  D/TestSync: doSomething start 0
01-01 13:46:22.986  D/TestSync: doSomething end 0

结论

synchronized关键字修饰一个方法,作用的对象是这个类,一个类并发调用这个方法可以顺序执行,但是多个相同的类调用这个方法,顺序就是不可控的,正常使用中一般都是对单例对象的一些方法使用synchronized关键字

使用synchronized 修饰对象或者.class

下面的代码效果是一样的,作用于类的.同一个类的多个对象,并发执行doSomething方法,可以保证执行顺序

public void doSomething2(int position) throws InterruptedException {
        synchronized(TestSync.class){
            Log.d("TestSync","doSomething start " + position);
            Thread.sleep(2000);
            Log.d("TestSync","doSomething end " + position);
        }
    }

或者

 private static final Object object = new Object();
 public void doSomething3(int position) throws InterruptedException {
        synchronized(object){
            Log.d("TestSync","doSomething start " + position);
            Thread.sleep(2000);
            Log.d("TestSync","doSomething end " + position);
        }
    }

结果

 doSomething start 1
 doSomething start 2
 doSomething start 0
doSomething end 1
doSomething end 2
doSomething end 0
上一篇下一篇

猜你喜欢

热点阅读