https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/package-summary.html
java.util.concurrent.locks.Lock接口用作类似于synchronized块的线程同步机制。 新的锁定机制比同步块更灵活,提供更多选项。 Lock和synchronized块之间的主要区别如下 :
保证顺序 - 同步块不提供任何顺序保证,等待线程将被授予访问权限。 锁接口处理它。
无超时 - 如果未授予锁定,则同步块没有超时选项。 Lock接口提供了这样的选项。
单个方法 - 同步块必须完全包含在单个方法中,而锁定接口的方法lock()和unlock()可以在不同的方法中调用。
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| package com.sinrail.lock;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
private static class Printer { private final Lock lock = new ReentrantLock();
public void print() { lock.lock(); try { final int duration = ThreadLocalRandom.current().nextInt(1000); System.out.println(Thread.currentThread().getName() + ": 打印花费时间:" + duration + " ms"); Thread.sleep(duration); } catch (InterruptedException e) { } finally { System.out.println(Thread.currentThread().getName() + ": 打印成功!"); lock.unlock(); } }
private static class Task extends Thread { private Printer printer;
public Task(String name, Printer printer) { super(name); this.printer = printer; }
@Override public void run() { System.out.println(Thread.currentThread().getName() + ": 开始打印..."); printer.print(); } }
public static void main(String[] args) { final Printer printer = new Printer();
new Task("task 1", printer).start(); new Task("task 2", printer).start(); new Task("task 3", printer).start(); new Task("task 4", printer).start(); } }
|
结果:
1 2 3 4 5 6 7 8 9 10 11 12
| task 2: 开始打印... task 1: 开始打印... task 3: 开始打印... task 4: 开始打印... task 2: 打印花费时间:641 ms task 2: 打印成功! task 1: 打印花费时间:662 ms task 1: 打印成功! task 3: 打印花费时间:590 ms task 3: 打印成功! task 4: 打印花费时间:481 ms task 4: 打印成功!
|
假如没有锁,代码这样写:
1 2 3 4 5 6 7 8 9 10 11 12
|
public void print() { try { final int duration = ThreadLocalRandom.current().nextInt(1000); System.out.println(Thread.currentThread().getName() + ": 打印花费时间:" + duration + " ms"); Thread.sleep(duration); System.out.println(Thread.currentThread().getName() + ": 打印成功!"); } catch (InterruptedException e) { } }
|
则得到的结果将不是顺序的:
1 2 3 4 5 6 7 8 9 10 11 12
| task 2: 开始打印... task 1: 开始打印... task 3: 开始打印... task 4: 开始打印... task 2: 打印花费时间:58 ms task 1: 打印花费时间:38 ms task 4: 打印花费时间:532 ms task 3: 打印花费时间:849 ms task 1: 打印成功! task 2: 打印成功! task 4: 打印成功! task 3: 打印成功!
|