1 Star 0 Fork 0

张罗一世 / program-lang

Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
TestLock.java 7.31 KB
Copy Edit Raw Blame History
张罗一世 authored 2021-09-08 10:58 . TestLock-4-deadLock2
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());
}
}
}
1
https://gitee.com/zl630/program-lang.git
git@gitee.com:zl630/program-lang.git
zl630
program-lang
program-lang
master

Search