Fetch the repository succeeded.
package juc;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.stream.IntStream;
/**
* Lock及ReentrantLock测试
* @author ben
* @date 2021-09-08 09:58:26 CST
*/
public class TestLock {
public static Consumer<Object> cs = System.out::println;
/**
* 锁
*/
// 非公平锁:T1执行完,T2才执行
// private static ReentrantLock glock = new ReentrantLock();
// 公平锁:T1、T2交叉执行
private static ReentrantLock glock = new ReentrantLock(true);
/**
* 单线程测试可重入:HoldCount会变化
*/
private static ReentrantLock glock2 = new ReentrantLock();
/**
* 共享变量
*/
private static Long accessCount = 0L;
public static void main(String[] args) throws Exception {
// test1();
// test2();
// deadLock();
deadLock2();
}
/**
* 死锁测试-lock()和unlock()数量不匹配
* 使用 jps+jstack -l 可以看到死锁状态
* @author ben
* @date 2021-09-08 10:47:09 CST
* @throws InterruptedException
*/
private static void deadLock2() throws InterruptedException {
cs.accept("程序开始...");
DeadLockClass2 dlc = new DeadLockClass2();
Thread t1 = new Thread(()->{
cs.accept("t1开始");
dlc.resource();
cs.accept("t1结束");
}, "T1");
Thread t2 = new Thread(()->{
cs.accept("t2开始");
dlc.resource();
cs.accept("t2结束");
}, "T2");
t1.start();
t2.start();
t1.join();
t2.join();
cs.accept("程序开始...");
}
/**
* 死锁测试
* 使用 jps+jstack -l 可以看到死锁状态
* @author ben
* @date 2021-09-08 10:19:26 CST
* @throws InterruptedException
*/
private static void deadLock() throws InterruptedException {
cs.accept("程序开始...");
DeadLockClass dlc = new DeadLockClass();
Thread t1 = new Thread(()->{
dlc.resource1();
}, "T1");
Thread t2 = new Thread(()->{
dlc.resource2();
}, "T2");
t1.start();
t2.start();
// 检查DeadLockClass的两个锁的状态
IntStream.range(0, 5).forEach(item->{
cs.accept("\ncheckLockStatus i=" + item);
DeadLockClass.checkLockStatus();
try {
TimeUnit.SECONDS.sleep(item+5);
} catch (InterruptedException e) {
}
});
t1.join();
t2.start();
cs.accept("程序结束...");
}
/**
* 测试可重入
* @author ben
* @date 2021-09-08 10:07:30 CST
* @throws InterruptedException
*/
private static void test2() throws InterruptedException {
String tname= Thread.currentThread().getName();
cs.accept(tname + ": holdCount=" + glock2.getHoldCount() + ", isHeld?=" + glock2.isHeldByCurrentThread());
IntStream.range(0, 6).forEach(item->{
glock2.lock();
cs.accept(tname + ": 锁住,holdCount=" + glock2.getHoldCount() + ", isHeld?=" + glock2.isHeldByCurrentThread());
});
cs.accept("---");
cs.accept(tname + ": holdCount=" + glock2.getHoldCount() + ", isHeld?=" + glock2.isHeldByCurrentThread());
int holdCount = glock2.getHoldCount();
for (int i=0; i<holdCount; i++) {
glock2.unlock();
cs.accept(tname + ": 释放,holdCount=" + glock2.getHoldCount() + ", isHeld?=" + glock2.isHeldByCurrentThread());
}
cs.accept("程序结束:");
cs.accept(tname + ": holdCount=" + glock2.getHoldCount() + ", isHeld?=" + glock2.isHeldByCurrentThread());
}
/**
* 测试1:main、T1、T2 访问共享资源
* @author ben
* @date 2021-09-08 09:57:27 CST
* @throws InterruptedException
*/
private static void test1() throws InterruptedException {
resource1(0);
// 建立两个线程访问共享资源
Thread t1 = new Thread(()->{
IntStream.range(0, 10).forEach(item->{
resource1(item);
});
}, "T1");
Thread t2 = new Thread(()->{
// 仅偶数参数
IntStream.range(10, 20).filter(item->{return item%2 == 0;}).forEach(item->{
resource1(item);
});
}, "T2");
t2.start();
t1.start();
t1.join();
t2.join();
cs.accept("程序结束...accessCount=" + accessCount);
}
/**
* 共享资源
* @author ben
* @date 2021-09-08 09:53:39 CST
* @param i
*/
private static void resource1(int i) {
String tname = Thread.currentThread().toString();
glock.lock();
cs.accept("lock: " + tname + ", i=" + i + ", hasQueuedThreads=" + glock.hasQueuedThreads());
try {
cs.accept(tname + ", holdCount=" + glock.getHoldCount() + ", qLen=" + glock.getQueueLength());
accessCount++;
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
cs.accept("interrupted: " + tname);
}
} finally {
cs.accept("unlock: " + tname + ", accessCount=" + accessCount + "\n");
glock.unlock();
}
}
}
/**
* 死锁测试类
* @author ben
* @date 2021-09-08 10:20:09 CST
*/
class DeadLockClass {
private static ReentrantLock lock1 = new ReentrantLock(true);
private static ReentrantLock lock2 = new ReentrantLock(true);
public static Consumer<Object> cs = System.out::println;
/**
* 检查锁的状态
* @author ben
* @date 2021-09-08 10:32:59 CST
*/
public static void checkLockStatus() {
cs.accept("lock1: " + lock1.getHoldCount() + "," + lock1.getQueueLength());
cs.accept("lock2: " + lock2.getHoldCount() + "," + lock2.getQueueLength());
}
/**
* 使用lock1
* @author ben
* @date 2021-09-08 10:25:23 CST
*/
public void resource1() {
String tname = Thread.currentThread().getName();
lock1.lock();
cs.accept(tname + ": lock1.lock");
try {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
}
// 调用资源2
cs.accept(tname + ": call resource2");
resource2();
} finally {
lock1.unlock();
cs.accept(tname + "lock1.unlock");
}
}
/**
* 使用lock2
* @author ben
* @date 2021-09-08 10:25:32 CST
*/
public void resource2() {
String tname = Thread.currentThread().getName();
lock2.lock();
cs.accept(tname + ": lock2.lock");
try {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
}
// 调用资源1
cs.accept(tname + ": call resource1");
resource1();
} finally {
lock2.unlock();
cs.accept(tname + ": lock2.unlock");
}
}
}
/**
* 死锁测试2——lock数量和unlock数量不匹配
* @author ben
* @date 2021-09-08 10:48:36 CST
*/
class DeadLockClass2 {
private static ReentrantLock glock = new ReentrantLock(true);
public static Consumer<Object> cs = System.out::println;
/**
* 检查锁的状态
* @author ben
* @date 2021-09-08 10:32:59 CST
*/
public static void checkLockStatus() {
cs.accept("glock: HoldCount=" + glock.getHoldCount() + ", QueueLength=" + glock.getQueueLength());
}
/**
* 共享资源
* @author ben
* @date 2021-09-08 10:54:20 CST
*/
public void resource() {
String tname = Thread.currentThread().getName();
cs.accept(tname + ": HoldCount=" + glock.getHoldCount() + ", QueueLength=" + glock.getQueueLength());
// 第一次lock
glock.lock();
cs.accept(tname + ": lock-1 HoldCount=" + glock.getHoldCount() + ", QueueLength=" + glock.getQueueLength());
try {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
// 第二次lock:错误!
glock.lock();
cs.accept(tname + ": lock-2 HoldCount=" + glock.getHoldCount() + ", QueueLength=" + glock.getQueueLength());
} finally {
glock.unlock();
cs.accept(tname + ": unlock-1 HoldCount=" + glock.getHoldCount() + ", QueueLength=" + glock.getQueueLength());
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。