ct var1);
我们先看看monitor同步相关的测试:
public void test4() {
Object obj = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " isrunning...");
unsafe.monitorEnter(obj);
System.out.println(Thread.currentThread().getName() + " got monitorEnter...");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " business over...");
} catch (Exception e) {
e.printStackTrace();
} finally {
unsafe.monitorExit(obj);
System.out.println(Thread.currentThread().getName() + " monitorExit...");
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " isrunning...");
unsafe.monitorEnter(obj);
System.out.println(Thread.currentThread().getName() + " got monitorEnter...");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " business over...");
} catch (Exception e) {
e.printStackTrace();
} finally {
unsafe.monitorExit(obj);
System.out.println(Thread.currentThread().getName() + " monitorExit...");
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
boolean flag = false;
try {
System.out.println(Thread.currentThread().getName() + " isrunning...");
flag = unsafe.tryMonitorEnter(obj);
System.out.println(Thread.currentThread().getName() + " tryMonitorEnter:" + flag);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (flag) {
unsafe.monitorExit(obj);
System.out.println(Thread.currentThread().getName() + " monitorExit...");
}
}
System.out.println(Thread.currentThread().getName() + " over...");
}
});
t1.start();
t2.start();
t3.start();
}
可能的一种输出如下(线程是根据系统分配资源调度的,输出先后顺序会有多种),下面的这个输出我们可以看到先输出3个线程都启动了,Thread-2尝试获取锁失败就结束了,然后Thread-0竞争到了对象锁,等Thread-0线程运行完毕释放了锁,Thread-1才会获取到锁继续执行直到结束释放锁。
Tips:
monitor相关的方法已经加了@deprecated注解,官方已经不再建议使用,可以换成其他锁或者同步方式
Thread-0 isrunning...
Thread-2 isrunning...
Thread-2 tryMonitorEnter:false
Thread-2 over...
Thread-1 isrunning...
Thread-0 got monitorEnter...
Thread-0 business over...
Thread-0 monitorExit...
Thread-1 got monitorEnter...
Thread-1 business over...
Thread-1 monitorExit...
我们在来看看park、unpark相关的使用
public void test5() throws Exception {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out
.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " is running...");
// 这里让当前线程阻塞6s,注意:如果park第一个参数是true的话,表示绝对时间,这个时间是毫秒级的,也就是系统时间,系统到这个绝对时间后才唤醒执行
unsafe.park(true, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(6));
System.out
.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " continue...");
// 这里让当前线程阻塞3s,注意:如果park第一个参数是false的话,这个是纳秒级别的时间,表示相对当前时间3s后继续唤醒执行
unsafe.park(false, TimeUnit.SECONDS.toNanos(3));
System.out
.println(LocalDateTime.now().format(formatter) + " " + Thread.currentThread().getName() + " continue...");
// 如果park的第一个参数是false,第二个值是0,则会一直等待,直