欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程之同步锁(Lock)

程序员文章站 2024-01-09 20:50:34
...

      从Java5开始,提供了Lock, Lock提供了比synchronized方法和synchronized代码块更广泛的锁定操作,Lock可以实现更灵活的结构,并且支持多个相关的Condition对象(对象监视器)。

      Lock是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。

示例代码:

ReentrantLockTest类:

public class ReentrantLockTest {

	private final ReentrantLock lock = new ReentrantLock();
        //创建10个线程
	public void userPrint() {
		for (int i = 0; i < 10; i++) {
			new Thread(new Runnable() {

				public void run() {
					print();
				}
			}).start();
		}
	}

	public void print() {
		lock.lock();
		System.out.println("线程" + Thread.currentThread().getName() + "正在使用打印机");
		try {
			Thread.sleep(new Random().nextInt(1000));
			System.out.println("线程" + Thread.currentThread().getName() + "资源使用打印机");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
                //获取等待得到同步锁的线程个数
		System.out.println("还剩 " + lock.getQueueLength() + "人要使用打印机");
		lock.unlock();
	}
}

Main类:

public class Main {
	
	public static void main(String[] args) throws Exception {
        new ReentrantLockTest().userPrint();
}

测试结果:

java多线程之同步锁(Lock)

可以看到我们创建的10个线程并没有同时进来使用打印机方法,而是每次至进入一个线程使用打印机。

Lock操作多个Condition对象:

实例代码:

ReentrantLockTest类:

public class ReentrantLockTest {

	private final ReentrantLock lock = new ReentrantLock();
	private Condition conditionA = lock.newCondition();
	private Condition conditionB = lock.newCondition();

	public void waitA() {
		lock.lock();
		try {
			System.out.println(Thread.currentThread().getName() + "等待条件");
			conditionA.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		lock.unlock();
	}

	public void waitB() {
		lock.lock();
		try {
			System.out.println(Thread.currentThread().getName() + "等待条件(没有人唤醒我,我将一直等待..)");
			conditionB.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		lock.unlock();
	}

	public void signal() throws InterruptedException {
		lock.lock();
		Thread.sleep(1000);
		System.out.println(Thread.currentThread().getName() + "执行完毕,唤醒A");
		conditionA.signal();
		lock.unlock();
	}

	public void condition() throws InterruptedException {
		new Thread(new Runnable() {

			public void run() {
				waitA();
			}
		}).start();
		new Thread(new Runnable() {

			public void run() {
				waitB();
			}
		}).start();
		new Thread(new Runnable() {

			public void run() {
				try {
					signal();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}).start();
	}
}

Mian类:

public class Main {
	
	public static void main(String[] args) throws Exception {
        new ReentrantLockTest().condition();
}

测试结果:

java多线程之同步锁(Lock)

上例中,我们可以看到我们创建了两个Condition对象,并且启动了三个线程,waitA和waitB方法都在其中一个线程执行,但是signal方法只唤醒了持有ConditionA的方法,而另一个waitB方法将一直等待被唤醒。使用Condition可以进行线程间的通信。

相关标签: thread java