猿来绘Java-36-解决线程安全问题中介绍了使用同步代码块、同步方法的方式解决线程安全问题,在JDK5.0之后,新增了使用ReentrantLock方式。
示例代码
//SynchronizedLockTest.java
package com.ylaihui.thread;
import java.util.concurrent.locks.ReentrantLock;
class ProcPicture implements Runnable{
private static int num = 100;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true) {
try{
lock.lock();
if (num > 0) {
System.out.println(Thread.currentThread().getName() + ":" + num);
num--;
} else
break;
}finally {
// 保证了释放锁一定能执行
lock.unlock();
}
}
}
}
public class SynchronizedLockTest {
public static void main(String[] args) {
ProcPicture p = new ProcPicture();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
t1.start();
t2.start();
t3.start();
}
}
总结:
1. synchronized 与 Lock的异同
相同:二者都可以解决线程安全问题
不同:synchronized机制在执行完相应的同步代码以后,自动的释放同步监视器,Lock需要手动的启动同步(lock()),同时结束同步也需要手动的实现(unlock())
2. 开发中我们如何选择使用哪种方式解决线程安全问题呢?
建议:优先使用灵活的
优先使用Lock的方式,其次同步代码块(已经进入了方法体,分配了相应资源),再次同步方法(在方法体之外)