多线程基础总结七--ReentrantLock
2010-01-22 00:00:00 来源:WEB开发网之前总结了部分无锁机制的多线程基础,理想的状态当然是利用无锁同步解决多线程程序设计的问题。但是实际碰到的问题使得很多情况下,我们不得不借助锁同步来保证线程安全。自从JDK5开始,有两种机制来屏蔽代码块在并行访问的干扰,synchronized关键字已经介绍过了部分内容,所以这次简单的说说另一种锁机制:ReentrantLock。
对于synchronized的缺点之前也简单的说了一些,实际使用中比较烦扰的几点是:a.只有一个"条件"与锁相关联,这对于大量并发线程的情况是很难管理(等待和唤醒);b.多线程竞争一个锁时,其余未得到锁的线程只能不停的尝试获得锁,而不能中断。这种情况对于大量的竞争线程会造成性能的下降等后果。JDK5以后提供了ReentrantLock的同步机制对于前面提的两种情况有相对的改善。下面我还是写个小例子分析一下:
Java代码
import java.util.concurrent.locks.ReentrantLock;
/**
* @author: yanxuxin
* @date: 2010-1-4
*/
public class ReentrantLockSample {
public static void main(String[] args) {
testSynchronized();
testReentrantLock();
}
public static void testReentrantLock() {
final SampleSupport1 support = new SampleSupport1();
Thread first = new Thread(new Runnable() {
public void run() {
try {
support.doSomething();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread second = new Thread(new Runnable() {
public void run() {
try {
support.doSomething();
}
catch (InterruptedException e) {
System.out.println("Second Thread Interrupted without executing counter++,beacuse it waits a long time.");
}
}
});
executeTest(first, second);
}
public static void testSynchronized() {
final SampleSupport2 support2 = new SampleSupport2();
Runnable runnable = new Runnable() {
public void run() {
support2.doSomething();
}
};
Thread third = new Thread(runnable);
Thread fourth = new Thread(runnable);
executeTest(third, fourth);
}
/**
* Make thread a run faster than thread b,
* then thread b will be interruted after about 1s.
* @param a
* @param b
*/
public static void executeTest(Thread a, Thread b) {
a.start();
try {
Thread.sleep(100);
b.start(); // The main thread sleep 100ms, and then start the second thread.
Thread.sleep(1000);
// 1s later, the main thread decided not to allow the second thread wait any longer.
b.interrupt();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
abstract class SampleSupport {
protected int counter;
/**
* A simple countdown,it will stop after about 5s.
*/
public void startTheCountdown() {
long currentTime = System.currentTimeMillis();
for (;;) {
long diff = System.currentTimeMillis() - currentTime;
if (diff > 5000) {
break;
}
}
}
}
class SampleSupport1 extends SampleSupport {
private final ReentrantLock lock = new ReentrantLock();
public void doSomething() throws InterruptedException {
lock.lockInterruptibly(); // (1)
System.out.println(Thread.currentThread().getName() + " will execute counter++.");
startTheCountdown();
try {
counter++;
}
finally {
lock.unlock();
}
}
}
class SampleSupport2 extends SampleSupport {
public synchronized void doSomething() {
System.out.println(Thread.currentThread().getName() + " will execute counter++.");
startTheCountdown();
counter++;
}
}
更多精彩
赞助商链接