重入 :
一般地,当一个线程请求由其他线程所持有的锁的资源时,发出请求的线程就会阻塞。
然而,内置锁是可以重入的。因此当一个线程获得由该线程已经持有的锁,那么这个线程的请求就会成功。重入意味着获取锁的的粒度是线程。
第一种synchronized关键字
public class Demo_001 implements Runnable {
@Override
public void run() {
set();
}
public synchronized void set(){
System.out.println("set method");
get();
}
public synchronized void get(){
System.out.println("get method");
}
public static void main(String[] args) {
Demo_001 demo_001 =new Demo_001();
Thread thread =new Thread(demo_001);
thread.start();
}
}
实现方式:重入的一种实现方式是为每个线程关联着一个计数器和一个所有者线程。当计数器的值为零的时候,表示没有线程池游该线程的锁,如果有线程请求持有该线程的锁,那么计数器+1,如果同一个线程再次获取这个值 计数器递增。代码退出同步代码块的时候计数器-1;
如果内置锁是不可重入的,那么上面的代码将会发生死锁。
第二种 ReentrantLock
package LockTest;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLock001 extends Thread {
ReentrantLock lock = new ReentrantLock();
public void set(){
try {
lock.lock();
System.out.println("excute set method");
get();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void get(){
try{
lock.lock();
System.out.println("excute get method");
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
@Override
public void run() {
set();
}
public static void main(String[] args) {
ReentrantLock001 reentrantLock001 =new ReentrantLock001();
reentrantLock001.start();
}
}