java synchronized 内置锁理解

synchronized的用法:站在对象锁和类锁的角度分析
对象锁和类锁的区别:

public  class SynchronizedClass {

    public synchronized void method(){
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"我是对象锁");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void method1(){
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"我是对象锁1");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static synchronized void method2(){
        for(int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"我是类锁");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public  void method3(){
        synchronized (SynchronizedClass.class) {
            for(int i=0;i<5;i++){
                System.out.println(Thread.currentThread().getName()+"我是类锁1");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedClass synchronizedClass = new SynchronizedClass();
        SynchronizedClass synchronizedClass1 = new SynchronizedClass();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method1();     //同一对象执行结果同步
//              synchronizedClass1.method1();  //不同对象执行结果异步


            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method2();     //类锁和对象锁异步
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedClass.method3();
            }
        }).start();
    }
}

1)多个线程访问同一对象的的同步代码时,只有一个线程能获取对象锁,其他的线程不能访问这个对象任何地方使用synchronized 修饰的代码必须等待或者阻塞,直到前面的线程释放锁,其他线程才能重新竞争锁。
2)多个线程访问不同对象的同步代码时,是互不干扰的,代码会异步执行
3)对象锁和类锁是互不干扰的,代码会异步执行

对象锁,锁的是类的对象实例。
写法有两种:
1)直接修饰方法

public synchronized void method(){
        System.out.println("我是对象锁");
    }

2)修饰代码块

public void method(){
		//dosomething  业务代码
		synchronized(this){
			System.out.println("我是对象锁");
		}//一个线程访问该对象的这个方法时候,另一个线程可以同时执行这个对象这个方法没用synchronized的代码
	}

两种写法都是对象锁,一个是锁整个方法,一个是锁方法中的一部分代码,当一个线程访问一个对象的同步代码时候,其他线程访问同一个对象的其他没用synchronized修饰的方法或方法中的代码时,会异步执行。

类锁 ,一个抽象出来的概念,锁的是每个类的的Class对象,每个类的的Class对象在一个虚拟机中只有一个,所以类锁也只有一个。规则和对象锁一致
写法有两种:
1)静态方法

public static synchronized void method(){
        System.out.println("我是类锁");
}

2)

   public void method(){
		synchronized (类名.class) {
			System.out.println("我是第二种类锁");
		}
	}

猜你喜欢

转载自blog.csdn.net/z278785324/article/details/84954984