一、synchronized 与 synchronized static区别?
synchronized:对像的当前实例进行加锁,防止其他线程同时访问该类实例的所有synchronized块。
synchronized static:是限制线程同时访问jvm中该类的所有实例同时访问对应的代码块,且该类的所有代码块共用一把锁。
pulbic class syncMethod(){public synchronized void syncA(){}public synchronized void syncB(){}public static synchronized void staticA(){}public static synchronized void staticB(){}}
假设上面的类有四个方法,然后有两个实例a,b调用,那么哪些可以同时被访问呢?
1、a.syncA() 和 a.syncB()。
2、a.syncA() 和 b.syncB()。
3、a.staticA() 和 b.staticB()。
4、a.staticA() 和 syncMethod.staticB()。
这里我们可以根据上面两个定律判断:
1、这个肯定是可以加锁成功,两个线程不能同时访问。
2、这个肯定加锁失败,两个线程可以同时访问。
3、这个因为是静态,而且是不同的实例,根据定律也是可以加锁成功,两个线程不能同时访问。
4、这里因为一个是实例方法锁,一个是类方法锁,锁的对象不同,所以可以被同时访问。
二、synchornized(this)和synchronized(.class)
对象锁只对当前对象进行加锁,锁this和synchronized普通方法一样,只对调用的实例进行加锁,而锁.class是指对类加锁。
synchornized(this)
public class Sync823 {public static void main(String[] args) {Service823 service823 = new Service823();ThreadA823 threadA823 = new ThreadA823(service823);threadA823.setName("鸣人");threadA823.start();Service823 service82311 = new Service823();ThreadB823 threadB823 = new ThreadB823(service823);threadB823.setName("佐助");threadB823.start();}}class Service823{void thread823(){synchronized (this){for (int i = 0; i < 100; i++) {if(Thread.currentThread().getName().equals("鸣人")){System.out.println("鸣人释放 螺旋丸");continue;}System.out.println("佐助释放 千鸟");}}}}class ThreadA823 extends Thread{private Service823 service823;ThreadA823(Service823 service823){this.service823 = service823;}@Overridepublic void run() {service823.thread823();}}class ThreadB823 extends Thread{private Service823 service823;ThreadB823(Service823 service823){this.service823 = service823;}@Overridepublic void run() {service823.thread823();}}鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸佐助释放 千鸟佐助释放 千鸟佐助释放 千鸟佐助释放 千鸟佐助释放 千鸟
从上面代码可以看到,当锁this的时候,当是同一个实例,这时候是上锁成功,两个线程不会同时访问,和前面的synchronized修饰普通方法一样,但如果换成 不同的实例,则不会互斥。
public static void main(String[] args) {Service823 service823 = new Service823();ThreadA823 threadA823 = new ThreadA823(service823);threadA823.setName("鸣人");threadA823.start();Service823 service82311 = new Service823();ThreadB823 threadB823 = new ThreadB823(service82311);threadB823.setName("佐助");threadB823.start();}佐助释放 千鸟佐助释放 千鸟鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸佐助释放 千鸟佐助释放 千鸟
synchronized(.class)
synchronized (Service823.class){for (int i = 0; i < 100; i++) {if(Thread.currentThread().getName().equals("鸣人")){System.out.println("鸣人释放 螺旋丸");continue;}System.out.println("佐助释放 千鸟");}}鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸鸣人释放 螺旋丸佐助释放 千鸟佐助释放 千鸟佐助释放 千鸟佐助释放 千鸟
这时候会发现,无论是创建几个实例,都会互斥成功,所以锁.class锁的是这个类,并不是实例。
文章转载自后端从入门到精通,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




