java中synchronized理解与使用

    xiaoxiao2021-12-14  20

    1.同步锁的基本理解

    当synchronized锁住一个对象后,别的线程如果也想拿到这个对象的锁,就必须等待这个线程执行完成释放锁,才能再次给对象加锁,这样才达到线程同步的目的。即使两个不同的代码段,都要锁同一个对象,那么这两个代码段也不能在多线程环境下同时运行。

    2.使用时要明白两个问题

    锁的对象是谁锁当前的持有者

    举例子说明: 例一:

    public class Test { public synchronized void methodA(String param) { System.out.println("methodA's param :" + param); } public synchronized void methodB(){ methodA("methodB"); } public static void main(String[] args) { Test test = new Test(); test.methodB(); } }

    执行结果:

    methodA’s param :methodB invoke

    分析: ① methodB被调用因为有synchronized需要获得一个锁,锁的对象是test,也就是当前Test类的实例,而获得所得东西是线程,也就是当前线程拿到了test的锁(不是B方法获得了锁) ② methodB内部调用了methodA,此时A也加了synchronized,也需要获得一个锁,因为A和B都是Test类中的方法,所以当前线程要获得的锁的对象也是test,而当前线程执行B方法时已经持有了test对象的锁,所以会直接调用methodA,相当于方法A上没有加synchronized。

    例二:

    public class Test { public synchronized void methodA(String param) { System.out.println("methodA's param :" + param); } public synchronized void methodB(){ methodA("methodB"); } public static void main(String[] args) { Test test1 = new Test(); Test test2 = new Test(); test1.methodB(); test2.methodB(); } }

    运行结果:

    methodA’s param :methodB methodA’s param :methodB

    分析: ① 执行test1.methodB()当前线程会持有test1对象的锁 ② 执行test2.methodB()当前线程会持有test2对象的锁 ③ 当前线程持有了两把锁,但是锁的对象不一样,所以互相没有影响

    例三:

    public class Test { public synchronized void methodA(String param) { System.out.println("methodA's param :" + param); } public synchronized void methodB(){ methodA("methodB"); } public static void main(String[] args) { Test test = new Test(); ThreadTest thread1 = test.new ThreadTest("thread1"); ThreadTest thread2 = test.new ThreadTest("thread2"); thread1.start(); thread2.start(); } class ThreadTest extends Thread { public ThreadTest(String name){ super(name); } public void run() { Test test = new Test(); test.methodB(); } } }

    运行结果:

    methodA’s param :methodB methodA’s param :methodB

    分析:

    ① thread1先获取test的锁 ② thread1执行methodB ③ thread1执行methodA ④ thread1释放test的锁 ⑤ thread2获得test的锁 ⑥ thread2执行methodB ⑦ thread2执行methodA ⑧ thread2释放test的锁

    总结:例三和例二结果一样,但是执行顺序却不同,另外synchronized还有很多种用法,在分析时一定要搞清楚哪个线程获得了哪个对象的锁,就很容易明白了。

    转载请注明原文地址: https://ju.6miu.com/read-971755.html

    最新回复(0)