同步的三种锁

  • 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁

当一个线程正在访问一个对象的 synchronized 实例方法,那么其他线程不能访问该对象的其他synchronized方法,毕竟一个对象只有一把锁,其他线程无法获取该对象的锁,但是其他线程还是可以访问该实例对象的其他非synchronized方法,

当然如果是一个线程 A 需要访问实例对象 obj1 synchronized 方法 f1(当前对象锁是obj1),另一个线程 B 需要访问实例对象 obj2 synchronized 方法 f2(当前对象锁是obj2),这样是允许的,因为两个实例对象锁并不相同,此时如果两个线程操作的是共享数据,那么线程安全就有可能无法保证了   这时就应该修饰静态方法

  • 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁

需要注意的是如果一个线程A调用一个实例对象的非static synchronized方法,而线程B需要调用这个实例对象所属类的静态 synchronized方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的class对象,而访问非静态 synchronized 方法占用的锁是当前实例对象锁   这种情况下可能会发现线程安全问题(操作了共享静态变量i)

  • 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码块前要获得给定对象的锁。

在某些情况下,我们编写的方法体可能比较大,同时存在一些比较耗时的操作,而需要同步的代码又只有一小部分,如果直接对整个方法进行同步操作,可能会得不偿失

除了instance作为对象外,我们还可以使用this对象(代表当前实例)或者当前类的class对象作为锁

posted @ 2020-03-23 17:06  BeeeenWei  阅读(222)  评论(0)    收藏  举报