JAVA多线程(三)Reentranlock 用法详解

Reentranlock 如果用于替代 synchronized

需要注意的是: 必须要手动释放锁。
使用synchronized 锁定的话,如果遇到异常。 jvm 会自动释放锁。 但是lock 必须手动释放锁。 因此经常在finally中进行锁的释放

public class ReentrantLock01 {
     
	Lock lock = new ReentrantLock();
	
	void m1() {
     
		try {
     
			lock.lock(); // 相当于 synchronized (this)
			for(int i=0; i < 10; i++) {
     
				try {
     
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
     
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(i);
			}
		} catch (Exception e) {
     
			// TODO: handle exception
		}finally {
     
			lock.unlock();  // 必须要手动释放锁 
		}
	}
	
	void m2() {
     
		lock.lock();
		System.out.println("m2....");
		lock.unlock();
	}
	
	public static void main(String[] args) {
     
		ReentrantLock01 lock01 = new ReentrantLock01();
		new Thread(lock01::m1).start();
		new Thread(lock01::m2).start();
	}
}

使用 ReentrantLock 还可以调用lockInterruptibly 方法,可以堆线程interrupt 方法做出响应。 在一个线程等待锁的过程中,可以被打断

使用tryLock 进行尝试锁定,不管锁定与否,方法都将继续执行
可以根据tryLock 的返回值来判定是否锁定
也可以指定tryLock的时间。由于tryLock(time) 抛出异常。 所以要注意unlock的处理。 必须放到finally中
public class ReentrantLock02 {
     
	Lock lock = new ReentrantLock();
	
	
	void m1() {
     
		lock.lock();
		try {
     
			for (int i = 0; i < 10; i++) {
     
				System.out.println(i);
				TimeUnit.SECONDS.sleep(1);
			}
		} catch (Exception e) {
     
			
		} finally {
     
			lock.unlock();
		}
	}
	/**
	 * 使用tryLock 进行尝试锁定,不管锁定与否,方法都将继续执行
	 * 可以根据tryLock 的返回值来判定是否锁定
	 * 也可以指定tryLock的时间。由于tryLock(time) 抛出异常。 所以要注意unlock的处理。 必须放到finally中
	 */
	void m2() {
     
		while (true) {
     
			boolean tryLock = false;
			try {
     
				TimeUnit.SECONDS.sleep(1);
				// 尝试去锁定
				tryLock = lock.tryLock();
				// 判断是否锁定成功
				if (tryLock) {
     
					// 如果成功  释放锁
					System.out.println("是否锁定" + tryLock);
					break;
				}else {
     
					// 不成功!
					System.out.println("是否锁定" + tryLock);
				}
			} catch (InterruptedException e) {
     
				e.printStackTrace();
			}finally {
     
				if (tryLock) {
     
					lock.unlock();
				}
			}
		}
	}
	
	void m3() {
     
		boolean locked = false;
		try {
     
			// 尝试锁定五秒钟。如果五秒钟拿不到锁
			locked = lock.tryLock(5,TimeUnit.SECONDS);
			System.out.println("m3..." + locked);
			// 判断是否锁定成功
			if (locked) {
     
				// 如果成功  释放锁
				System.out.println("是否锁定" + locked);
			
			}else {
     
				// 不成功!
				System.out.println("是否锁定" + locked);
			}
		} catch (InterruptedException e) {
     
			e.printStackTrace();
		} finally{
     
			if (locked) {
     
				lock.unlock();
			}
		}
	}
	
	
	public static void main(String[] args) {
     
		ReentrantLock02 lock02 = new ReentrantLock02();
		new Thread(lock02::m1).start();;
		new Thread(lock02::m3).start();;
	}
}

ReentrantLock 还可以指定为公平锁

参数true表示为公平锁。请对比输出结果

public class ReentrantLock03 extends Thread {
     
	private static ReentrantLock lock = new ReentrantLock(false); // 参数true表示为公平锁。请对比输出结果
	
	@Override
	public void run() {
     

		try {
     
			for (int i = 0; i < 100; i++) {
     
				lock.lock();
				System.out.println(Thread.currentThread().getName() + "获得锁");
				lock.unlock();
			}
		} finally {
     
			
		}
	}
	
	public static void main(String[] args) {
     
		ReentrantLock03 lock03 = new ReentrantLock03();
		new Thread(lock03).start();
		new Thread(lock03).start();
	}
}

true时输出结果:
Thread-1获得锁
Thread-2获得锁
Thread-1获得锁
Thread-2获得锁
Thread-1获得锁
Thread-2获得锁
Thread-1获得锁
Thread-2获得锁
Thread-1获得锁
false时输出结果:
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe"
Thread-1获得锁
Thread-1获得锁
Thread-1获得锁
Thread-1获得锁
Thread-1获得锁
Thread-2获得锁
Thread-2获得锁
Thread-2获得锁
Process finished with exit code 0

你可能感兴趣的:(Java,多线程,JAVA,多线程,Reentranlock)