一柬唯、方法如下
public native void unpark(Object var1);
public native void park(boolean var1, long var2);
二认臊、使用說明
park:將當(dāng)前線程掛起。unpark:精準(zhǔn)的喚醒某個(gè)線程锄奢。
park的參數(shù)失晴,表示掛起的到期時(shí)間冤议,第一個(gè)如果是true,表示絕對(duì)時(shí)間师坎,則var2為絕對(duì)時(shí)間值恕酸,單位是毫秒。第一個(gè)參數(shù)如果是false胯陋,表示相對(duì)時(shí)間蕊温,則var2為相對(duì)時(shí)間值,單位是納秒遏乔。
unpark的參數(shù)义矛,表示線程。
簡(jiǎn)單示例:
park(false,0) 表示永不到期盟萨,一直掛起凉翻,直至被喚醒
long time = System.currentTimeMillis()+3000;
park(true,time + 3000) 表示3秒后自動(dòng)喚醒
park(false,3000000000L) 表示3秒后自動(dòng)喚醒
三、測(cè)試示例
package com.suncy.article.article5;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class ParkTest {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InterruptedException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
//線程1必須等待喚醒
Thread thread1 = new Thread(() -> {
System.out.println("線程1:執(zhí)行任務(wù)");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("線程1:掛起捻激,等待喚醒才能繼續(xù)執(zhí)行任務(wù)");
unsafe.park(false, 0);
System.out.println("線程1:執(zhí)行完畢");
});
thread1.start();
//線程2必須等待喚醒
Thread thread2 = new Thread(() -> {
System.out.println("線程2:執(zhí)行任務(wù)");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("線程2:掛起制轰,等待喚醒才能繼續(xù)執(zhí)行任務(wù)");
unsafe.park(false, 0);
System.out.println("線程2:執(zhí)行完畢");
});
thread2.start();
Thread.sleep(5000);
System.out.println("喚醒線程2");
unsafe.unpark(thread2);
Thread.sleep(1000);
System.out.println("喚醒線程1");
unsafe.unpark(thread1);
//線程3自動(dòng)喚醒
Thread thread3 = new Thread(() -> {
System.out.println("線程3:執(zhí)行任務(wù)");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("線程3:掛起,等待時(shí)間到自動(dòng)喚醒");
unsafe.park(false, 3000000000L);
System.out.println("線程3:執(zhí)行完畢");
});
thread3.start();
//線程4自動(dòng)喚醒
Thread thread4 = new Thread(() -> {
System.out.println("線程4:執(zhí)行任務(wù)");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("線程4:掛起胞谭,等待時(shí)間到自動(dòng)喚醒");
long time = System.currentTimeMillis() + 3000;
unsafe.park(true, time);
System.out.println("線程4:執(zhí)行完畢");
});
thread4.start();
}
}
測(cè)試結(jié)果:
image.png
四垃杖、目的
1、使用Unsafe中的park和unpark和上篇文章說的《Unsafe中的CAS》可以完成一個(gè)自己的鎖丈屹,這應(yīng)該是并發(fā)編程基礎(chǔ)的前提條件调俘。