Java Concurrency 简明教程

Java Concurrency - Lock Interface

java.util.concurrent.locks.Lock 接口用作与同步块类似的线程同步机制。新的锁定机制更加灵活,并提供比同步块更多的选项。Lock 与同步块之间的主要区别如下 −

A java.util.concurrent.locks.Lock interface is used to as a thread synchronization mechanism similar to synchronized blocks. New Locking mechanism is more flexible and provides more options than a synchronized block. Main differences between a Lock and a synchronized block are following −

  1. Guarantee of sequence − Synchronized block does not provide any guarantee of sequence in which waiting thread will be given access. Lock interface handles it.

  2. No timeout − Synchronized block has no option of timeout if lock is not granted. Lock interface provides such option.

  3. Single method − Synchronized block must be fully contained within a single method whereas a lock interface’s methods lock() and unlock() can be called in different methods.

Lock Methods

以下是 Lock 类中可用的重要方法列表。

Following is the list of important methods available in the Lock class.

Sr.No.

Method & Description

1

public void lock() Acquires the lock.

2

public void lockInterruptibly() Acquires the lock unless the current thread is interrupted.

3

public Condition newCondition() Returns a new Condition instance that is bound to this Lock instance.

4

public boolean tryLock() Acquires the lock only if it is free at the time of invocation.

5

public boolean tryLock(long time, TimeUnit unit) Acquires the lock if it is free within the given waiting time and the current thread has not been interrupted.

6

public void unlock() Releases the lock.

Example

以下 TestThread 程序展示了 Lock 接口的其中一些方法。此处我们使用了 lock() 获取锁,使用了 unlock() 释放锁。

The following TestThread program demonstrates some of these methods of the Lock interface. Here we’ve used lock() to acquire the lock and unlock() to release the lock.

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

class PrintDemo {
   private final Lock queueLock = new ReentrantLock();

   public void print() {
      queueLock.lock();

      try {
         Long duration = (long) (Math.random() * 10000);
         System.out.println(Thread.currentThread().getName()
            + "  Time Taken " + (duration / 1000) + " seconds.");
         Thread.sleep(duration);
      } catch (InterruptedException e) {
         e.printStackTrace();
      } finally {
         System.out.printf(
            "%s printed the document successfully.\n", Thread.currentThread().getName());
         queueLock.unlock();
      }
   }
}

class ThreadDemo extends Thread {
   PrintDemo  printDemo;

   ThreadDemo(String name,  PrintDemo printDemo) {
      super(name);
      this.printDemo = printDemo;
   }

   @Override
   public void run() {
      System.out.printf(
         "%s starts printing a document\n", Thread.currentThread().getName());
      printDemo.print();
   }
}

public class TestThread {

   public static void main(String args[]) {
      PrintDemo PD = new PrintDemo();

      ThreadDemo t1 = new ThreadDemo("Thread - 1 ", PD);
      ThreadDemo t2 = new ThreadDemo("Thread - 2 ", PD);
      ThreadDemo t3 = new ThreadDemo("Thread - 3 ", PD);
      ThreadDemo t4 = new ThreadDemo("Thread - 4 ", PD);

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

这将产生以下结果。

This will produce the following result.

Output

Thread - 1  starts printing a document
Thread - 4  starts printing a document
Thread - 3  starts printing a document
Thread - 2  starts printing a document
Thread - 1   Time Taken 4 seconds.
Thread - 1  printed the document successfully.
Thread - 4   Time Taken 3 seconds.
Thread - 4  printed the document successfully.
Thread - 3   Time Taken 5 seconds.
Thread - 3  printed the document successfully.
Thread - 2   Time Taken 4 seconds.
Thread - 2  printed the document successfully.

这里我们使用 ReentrantLock 类作为 Lock 接口的实现。ReentrantLock 类允许一个线程锁定方法,即使它已经在另一个方法上拥有锁。

We’ve use ReentrantLock class as an implementation of Lock interface here. ReentrantLock class allows a thread to lock a method even if it already have the lock on other method.