Java可重入的互斥锁

Lock是JDK5引入的,可重入的互斥锁

使用可重入的互斥锁,重写 http://www.qiufengblog.com/articles/java-synchronized.html ,了解可重入互斥锁.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket2 implements Runnable {

	private int tickets = 100;

	private final Lock lock = new ReentrantLock();

	@Override
	public void run() {
		do {
			// 如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1
			// 如果当前线程已经保持该锁,则将保持计数加 1,并且该方法立即返回。
			// 如果该锁被另一个线程保持,则出于线程调度的目的,禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态,此时锁保持计数被设置为 1。
			lock.lock();
			if (tickets > 0) {
				System.out.println(Thread.currentThread().getName() + "出售票" + (tickets--));
			}
			// 试图释放此锁。
			// 如果当前线程是此锁所有者,则将保持计数减 1。如果保持计数现在为 0,则释放该锁。
			lock.unlock();
		} while (tickets > 0);
	}

}


public static void main(String[] args) {
	Ticket2 ticket = new Ticket2();
	Thread t1 = new Thread(ticket, "窗口1");
	Thread t2 = new Thread(ticket, "窗口2");
	Thread t3 = new Thread(ticket, "窗口3");
	Thread t4 = new Thread(ticket, "窗口4");

	t1.start();
	t2.start();
	t3.start();
	t4.start();
}

推荐使用

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket2 implements Runnable {

	private int tickets = 100;

	private final Lock lock = new ReentrantLock();

	@Override
	public void run() {
		//官方文档建议在try之前加锁
		lock.lock();  
		try {
			do {
				if (tickets > 0) {
					System.out.println(Thread.currentThread().getName() + "出售票" + (tickets--));
				}
			} while (tickets > 0);
		} finally {
			// 在finally中,即使出现异常也可以释放锁,因为finally总是执行的
			lock.unlock();

		}
	}

}
秋风 2017-07-05