技术栈

2019-04-21——Java并发包 锁 synchroniz

2019-04-21  本文已影响0人  烟雨乱平生

在Java中,每一个对象都拥有一个锁标记(monitor),也称为监视器,多线程同时访问某个对象时,线程只有获取了该对象的锁才能访问。

在Java中,可以使用synchronized关键字来标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时,这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,这个线程才会释放该对象的锁,其他线程才能执行这个方法或者代码块。

作用

synchronized的作用主要有三个

作用域

synchronized关键字的作用域有二种:

/*锁是当前实例对象*/
synchronized void t1(){
    System.out.println("这是对象锁");
}

/*锁是当前类的class对象*/
static synchronized void t2(){
    System.out.println("这是类锁");
}
void t3(){
    synchronized (Synchronized.class){
        System.out.println("锁对象是Synchronized.class");
    }
}

void t4(){
    synchronized (this){
        System.out.println("锁对象是this");
    }
}

private byte[] lock = new byte[0];
void t5(){
    synchronized (lock){
        System.out.println("锁对象是lock");
    }
}

在锁代码块的时候,所对象除了this外,还可以使用类对象以及其他对象

零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

synchronize的可重入性:

从互斥锁的设计上来说,当一个线程试图操作一个由其他线程持有的对象锁的临界资源时,将会处于阻塞状态,但当一个线程再次请求自己持有对象锁的临界资源时,这种情况属于重入锁,请求将会成功,在java中synchronized是基于原子性的内部锁机制,是可重入的,因此在一个线程调用synchronized方法的同时在其方法体内部调用该对象另一个synchronized方法,也就是说一个线程得到一个对象锁后再次请求该对象锁,是允许的,这就是synchronized的可重入性。

对于synchronized方法或者synchronized代码块,当出现异常时,JVM会自动释放当前线程占用的锁,因此不会由于异常导致出现死锁现象。

锁释放

如果一个代码块被synchronized关键字修饰,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待直至占有锁的线程释放锁。事实上,占有锁的线程释放锁一般会是以下三种情况之一:


上一篇 下一篇

猜你喜欢

热点阅读