synchronized和锁(ReentrantLock) 区别
java的两种同步方式, Synchronized与ReentrantLock的区别
可重入锁和不可重入锁 ReentrantLock & synchronize
package mianshi.test; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; class ReentrantLockTest {
public static ReentrantLock reenT = new ReentrantLock();// 参数默认false,不公平锁
private ReentrantLock lock = new ReentrantLock(true); // 公平锁 速度慢与不公平锁 /**
* 使用场景:(1)比如一个定时任务,第一次定时任务未完成,重复发起了第二次,直接返回flase;
* (2)用在界面交互时点击执行较长时间请求操作时,防止多次点击导致后台重复执行
*/
public static void tryLockTest() {
if (reenT.tryLock()) {
// 如果已经被lock,则立即返回false不会等待,
// 达到忽略操作的效果 ,当执行1000线程时,有些未获得对象锁的线程,会自动跳过
try {
// 操作
System.out.println("aaaa" + Thread.currentThread().getName());
} finally {
reenT.unlock();
} }
} /**
* 使用场景:(1)同步操作 类似于synchronized 如果被其它资源锁定,会在此等待锁释放,达到暂停的效果
* ReentrantLock存在公平锁与非公平锁 而且synchronized都是公平的
*/
public static void lockTest() {
try {
reenT.lock(); // 如果被其它资源锁定,会在此等待锁释放,达到暂停的效果
// 操作
System.out.println("aaaa" + Thread.currentThread().getName()); } finally {
reenT.unlock();
}
} /**
* 使用场景:(1)如果发现该操作正在执行,等待一段时间,如果规定时间未得到锁,放弃。防止资源处理不当,线程队列溢出,出现死锁
*/
public static void trylockTimeTest() {
try {
if (reenT.tryLock(5, TimeUnit.SECONDS)) { // 如果已经被lock,尝试等待5s,看是否可以获得锁,如果5s后仍然无法获得锁则返回false继续执行
Thread.sleep(6000);
try {
// 操作
System.out.println("aaaa"
+ Thread.currentThread().getName());
} finally {
reenT.unlock();
}
}
System.out
.println("如果发现该操作正在执行,等待一段时间,如果规定时间未得到锁,放弃。防止资源处理不当,线程队列溢出,出现死锁");
} catch (InterruptedException e) {
e.printStackTrace(); // 当前线程被中断时(interrupt),会抛InterruptedException
} } /**
* 使用场景:(1)中断正在进行的操作立刻释放锁继续下一操作.比如 取消正在同步运行的操作,来防止不正常操作长时间占用造成的阻塞
*/
public static void lockInterruptTest() {
try {
reenT.lockInterruptibly();
System.out.println("aaaa" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reenT.unlock();
}
System.out.println("(1)中断正在进行的操作立刻释放锁继续下一操作.比如 取消正在同步运行的操作,来防止不正常操作长时间占用造成的阻塞");
} public void testlockInterruptTest() throws Exception {
final java.util.concurrent.locks.Lock lock = new ReentrantLock();
lock.lock();//长时间持有锁不释放,使用lockInterruptibly中断异常!!!
Thread.sleep(1000);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
/*try{
lock.lock();
System.out.println("不会中断");
}finally{
lock.unlock();
}*/
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " interrupted.");
}
});
t1.start();
Thread.sleep(1000);
t1.interrupt();
} public static void main(String[] args) { for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
public void run() {
ReentrantLockTest.lockInterruptTest();
}
}).start();
} /*try {
ReentrantLockTest t = new ReentrantLockTest();
t.testlockInterruptTest();
} catch (Exception e) {
e.printStackTrace();
}*/
} }