synchronized三种使用方式,及锁的类型验证

Synchronized常用三种使用方式

1、修饰普通方法:锁对象即为当前对象

2、修饰静态方法:锁对象为当前Class对象

3、修饰代码块:锁对象为synchronized紧接着的小括号内的对象

一、验证修饰普通方法时锁对象

package com.demo;

public class ThreadTest {

    public static void main(String[] args) {
        Thread t1 = new MyThread1();
        Thread t2 = new MyThread2(t1);

        t1.start();// 默认priority=5
        t2.start();

        t2.setPriority(9);
System.out.println(
"线程1:" + t1.getState()); System.out.println("线程2:" + t2.getState()); } } class MyThread1 extends Thread { @Override public void run() { dosome(); } public synchronized void dosome() { System.out.println("mythread1"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("sleep end"); } } class MyThread2 extends Thread { private Object lock; public MyThread2(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println("mythread2"); } } }

现象:先逐行输出mythread1,线程1:RUNNABLE,线程2:BLOCKED,之后暂停五分钟,逐行输出sleep end,mythread2

分析:线程2与线程1拥有相同的锁,线程1优先级高于线程2,线程1优先执行,获取到锁,执行sleep,未释放锁,线程2未获取到锁,处于阻塞状态,线程1sleep结束,输出sleep end,并释放锁,线程2获取到锁,执行输出mythread2

结论:当synchronized修饰普通方法时,锁对象即为当前对象

二、验证修饰静态方法时锁对象

对上述代码稍作修改,在dosome方法上添加static关键字,main方法中,线程2对象初始化时,传入MyThread1.class

现象:与上述现象一致

分析:同上

结论:当synchronized修饰静态方法时,锁对象为当前Class对象

三、验证修饰代码块时锁对象

package com.demo;

public class ThreadTest {

    public static void main(String[] args) {
        Object o = new Object();

        Thread t1 = new MyThread1(o);
        Thread t2 = new MyThread2(o);

        t1.start();
        t2.start();

        t2.setPriority(9);
        System.out.println("线程1:" + t1.getState());
        System.out.println("线程2:" + t2.getState());

    }

}

class MyThread1 extends Thread {
    private Object lock;

    public MyThread1(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {

        synchronized (lock) {
            System.out.println("mythread1");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sleep end");
        }
    }

}

class MyThread2 extends Thread {
    private Object lock;

    public MyThread2(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println("mythread2");
        }
    }

}

现象:同上

分析:同上

结论:当使用synchronized修改代码块时,其后小括号中的对象即为对象锁。

 

posted @ 2019-05-08 11:49  大坑水滴  阅读(2539)  评论(0编辑  收藏  举报