synchronized关键字

synchronized关键字的用法详解:

第一个用法:对象锁

  代码块形式:手动指定锁对象;

Object lock1 = new Object();
Object lock2 = new Object();

    @Override
    public void run() {
        synchronized (lock1) {
            System.out.print("线程:" + Thread.currentThread().getName() + "的lock1开始啦\n");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print("线程:" + Thread.currentThread().getName() + "的lock1结束啦\n");
        }
        synchronized (lock2) {
            System.out.print("线程:" + Thread.currentThread().getName() + "的lock2开始啦\n");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print("线程:" + Thread.currentThread().getName() + "的lock2结束啦\n");
        }
    }

  方法锁形式:synchronized修饰普通的方法,锁对象默认为this;

public synchronized void method(){
        System.out.print("线程:" + Thread.currentThread().getName() + "的lock1开始啦\n");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.print("线程:" + Thread.currentThread().getName() + "的lock1结束啦\n");
    }
public void run() {
      method();  
}

 

第二个用法:类锁

  java类有很多个对象,但是只有一个类(class), 类锁即是class对象的锁。

  形式1:static 方法加锁;

@Override
    public void run() {
        method();
    }
    //类锁1
    static synchronized void method(){
        System.out.print("线程:" + Thread.currentThread().getName() + "的类锁1开始啦\n");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.print("线程:" + Thread.currentThread().getName() + "的类锁1结束啦\n");

    }

  形式2:synchronized(*.class);

@Override
    public void run() {
        synchronized (SynchronizedRequest2.class){
            System.out.print("线程:" + Thread.currentThread().getName() + "的类锁1开始啦\n");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print("线程:" + Thread.currentThread().getName() + "的类锁1结束啦\n");
        }
    }

 

对象锁是实例级别的锁,所以在测试类中,只要使用同一个类的单例runnable就可以让线程1和线程2串行化执行;

类锁是类级别的锁,所以在测试类中,需要检验的是同一个类的不同实例。

 

可重入性:

锁的可重入性质是线程级别的,与对象无关。无论是递归,两个同步方法,继承类的重写同步方法,都可以重入。

posted @ 2019-12-11 17:19  碧落君  阅读(250)  评论(0编辑  收藏  举报