join()、park()、yield()会不会释放当前线程持有的锁?
https://www.cnblogs.com/kitor/p/14724244.html
stop()、suspend()、Thread.sleep()都不会释放线程所持有的锁。但join()、park()、yield()会不会释放当前线程持有的锁?下面通过一些实例来验证一下
代码如下
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
public class ThreadLockTest {
public static void main(String[] args) throws InterruptedException {
// yieldTest(10);
// parkTest();
// joinTest();
}
/**
* 测试yield会不会释放锁:yield调用的是本地方法,建议seconds设置大一些结果更明显
* 结论:yield不会释放线程持有的锁
*
* @param seconds
*/
private static void yieldTest(int seconds) {
String lock = "lock";
//首先执行并获得锁
Thread preThread = new Thread() {
@Override
public void run() {
synchronized (lock) {
log("=============获取了锁==============");
long start = System.currentTimeMillis();
while (true) {
//将让出当前线程的执行权,线程状态由RUNNING ----> RUNNABLE
log(".........yield()被调用");
yield();
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis - start >= 1000 * seconds) {
log("---------释放锁并结束线程");
break;
}
}
}
}
};
preThread.setName("preThread");
preThread.start();
//在preThread之后执行的线程
new Thread(() -> {
try {
Thread.sleep(1000);
synchronized (lock) {
log("=============获取了锁==============");
}
} catch (InterruptedException e) {
}
},"postThread").start();
}
/**
* 测试park会不会释放锁
* 结论:park不会释放线程持有的锁
*/
private static void parkTest() throws InterruptedException {
String lock = "lock";
首先执行并获得锁
Thread preThread = new Thread(() -> {
log("运行....");
synchronized (lock) {
log("=============获取了锁==============");
log(".........park被调用");
//没被唤醒就会一直等待
LockSupport.park();
log("被unpark.....");
}
},"preThread");
preThread.start();
//在preThread之后执行的线程
new Thread(() -> {
try {
log("运行....");
Thread.sleep(100);
log("+++++++++等待获取锁");
synchronized (lock) {
log("=============获取了锁==============");
}
} catch (InterruptedException e) {
}
},"postThread").start();
//主线程等待10秒,然后唤醒preThread线程
TimeUnit.SECONDS.sleep(10);
log("主线程唤醒unpark....");
LockSupport.unpark(preThread);
}
/**
* 测试 join 会不会释放锁
* 结论:join不会释放线程持有的锁
*/
private static void joinTest() {
String lock = "lock";
//任务线程
Thread taskThread = new Thread(() -> {
log("*********任务线程启动!");
long currentTimeMillis = System.currentTimeMillis();
while (true) {
//执行任务需要10秒
if (System.currentTimeMillis() - currentTimeMillis > 10000) {
log("任务执行完毕!*********");
return;
}
}
},"taskthread");
//首先执行并获得锁
Thread preThread = new Thread(() -> {
log("运行....");
try {
synchronized (lock) {
log("=============获取了锁==============");
//启动线程2并一直等待线程taskThread完成
taskThread.start();
log(".........join被调用");
taskThread.join();
log("---------join执行完毕");
}
} catch (InterruptedException e) {
}
},"preThread");
preThread.start();
//在preThread之后执行的线程
Thread postThread = new Thread(() -> {
try {
log("运行....");
Thread.sleep(1000);
log("+++++++++等待获取锁");
synchronized (lock) {
log("=============获取了锁==============");
}
} catch (InterruptedException e) {
}
},"postThread");
postThread.start();
}
/**
* 日志打印
*
* @param msg
*/
private static void log(String msg) {
System.out.println(new Date() + " " + Thread.currentThread().getName() + " " + msg);
}
}
运行结果可以自定粘贴运行,结论如下
join()、park()、yield()不会释放当前线程持有的锁!