传说有一本江湖罕见的武功秘籍,该书珍藏在主持大师手中。一天大师盛情邀请江湖好汉前来观摩该书,但是一次只能有一个人来看。

该怎么办呢?用synchronized来实现吗?都用臭了,算了。用下李狗(Doug Lea)写的Lock吧。

实现很简单,首先获得一个锁实例

Lock lock = new ReentrantLock();

接着获得一把锁:

lock.lock();

观摩该书中。。。

lock.unlock();

在lock()和unlock()之间就是传说中操作系统中的critical section(临界区域),一次只能有一个线程访能够访问到。

废话不多说,看一个简单的例子:

[java]

package org.ninnjya.locks;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

class 武功秘籍 {

private Lock lock;

public 武功秘籍() {

lock = new ReentrantLock(true); // 公平锁

}

public void 观看武功秘籍(String 读者) {

System.out.println(读者 + "欲观看该书!");

lock.lock(); // 获取该锁

try {

System.out.println(读者 + "开始阅读...");

TimeUnit.SECONDS.sleep((long) (Math.random() * 10)); // 每位好汉

读书是需要不同时间的。耐心等下吧

System.out.println("想练此功,必先自宫。");

System.out.println("还是算了。。。 88 ");

} catch (Exception e) {

e.printStackTrace();

} finally {

lock.unlock(); // 切忌看完后记得返还该书,别太自私了

}

}

}

class 读者 implements Runnable {

private 武功秘籍 book;

private String 好汉名;

public 读者(武功秘籍 book,String 好汉名) {

this.book = book;

this.好汉名 = 好汉名;

}

@Override

public void run() {

book.观看武功秘籍(好汉名);

}

}

public class Main {

public static void main(String args[]) {

武功秘籍 book = new 武功秘籍(); // 只有一本武功秘籍

Runnable[] readers = new Runnable[10]; // 10位武林好汉

for (int i = 0; i < readers.length; i++) {

readers[i] = new 读者(book,"读者" + (i+1));

}

ExecutorService 主持大师 = Executors.newCachedThreadPool(); // 将书交给主持大师保管

for (Runnable reader : readers) {

主持大师.execute(reader);  // 大师决定将书交给谁看

}

主持大师.shutdown(); // 住持回家吃斋了

}

}

下面是控制台输出的一部分:

[plain]

读者1欲观看该书!

读者1开始

阅读...

读者2欲观看该书!

读者3欲观看该书!

读者4欲观看该书!

读者5欲观看该书!

读者6欲观看该书!

读者7欲观看该书!

读者8欲观看该书!

读者9欲观看该书!

读者10欲观看该书!

想练此功,必先自宫。

还是算了。。。 88

读者2开始阅读...

想练此功,必先自宫。

还是算了。。。 88

读者3开始阅读...

想练此功,必先自宫。

还是算了。。。 88

读者4开始阅读...

想练此功,必先自宫。

还是算了。。。 88

读者5开始阅读...

想练此功,必先自宫。

还是算了。。。 88

读者6开始阅读...

想练此功,必先自宫。

还是算了。。。 88

记得调用了lock方法后,需在finally(finally确保一定会执行,除非执行了exit方法)语句里调用unlock方法。否则会造成死锁等问题。

这里用中文来表示类名和变量名只是为了便于阅读。实际情况下切勿这样写。

本文分享 CSDN - 田维常。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

Logo

更多推荐