Bra*_*exe 17 java multithreading
我有几个问题Unsafe.park和Object.wait(及其相应的简历方法):
Unsafe.park结束有什么好处Object.wait吗?Aja*_*jax 15
最有效的等待是LockSupport.park/unpark,不需要令人讨厌(直接)使用Unsafe,并且不支付重新同步线程的本地内存缓存.
这一点很重要; 你做的工作越少,效率越高.通过不同步任何东西,你不需要付费让你的线程检查主内存以获取来自其他线程的更新.
在大多数情况下,这不是你想要的.在大多数情况下,您希望线程看到"之前"发生的所有更新,这就是您应该使用Object.wait()和.notify()的原因,因为您必须同步内存状态才能使用它们.
LockSupport允许您在给定时间内安全地停放线程,并且只要没有其他线程试图取消停止,它将等待那么长时间(禁止虚假唤醒).如果您需要等待特定的时间,您需要重新检查截止日期并循环回park()直到该时间已经过去.
您可以使用它来有效地"睡眠",而无需另一个线程通过LockSupport.parkNanos或唤醒您.parkUntil(对于毫秒;两种方法都只是为您调用Unsafe).
如果你确实希望其他线程唤醒你,你很可能需要内存同步,并且不应该使用park(除非仔细编排没有竞争条件的易失性字段).
祝你好运,编码愉快!
Max*_*000 13
如果您是应用程序员,则不应该使用这些方法中的任何一种.
它们都是太低级别,容易搞砸并且不打算在库外使用.
为什么不尝试使用更高级别的构造,如java.util.concurrent.locks?
回答你的问题.park(...)直接在线程上工作.它将线程作为参数并将其置于休眠状态,直到在线程上调用unpark,除非已经调用了unpark.
它应该比Object.wait()更快,如果您知道需要阻塞/解除阻塞的线程,它将在监视器抽象上运行.
顺便说一下,如果从Java内部使用, unpark并不是那么不安全:
public native void unpark(Object thread)取消阻止在停放时阻止的给定线程,或者,如果它未被阻止,则导致后续呼叫暂停不阻止.注意:此操作"不安全"仅仅是因为调用者必须以某种方式确保线程未被销毁.从Java调用时通常不需要特殊的东西(通常会有一个对线程的实时引用),但是当从本机代码调用时,这几乎不是自动的.
LockSupport.park/unpark 具有更好的性能,但它的 API 级别太低。
此外,它们有一些不同的操作,也许您应该注意到:
Object lockObject = new Object();
Runnable task1 = () -> {
synchronized (lockObject) {
System.out.println("thread 1 blocked");
try {
lockObject.wait();
System.out.println("thread 1 resumed");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread thread1 = new Thread(task1);
thread1.start();
Runnable task2 = () -> {
System.out.println("thread 2 running ");
synchronized (lockObject) {
System.out.println("thread 2 get lock");
lockObject.notify();
}
};
Thread thread2 = new Thread(task2);
thread2.start();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,线程 2 可以获得锁并通知线程 1 恢复,因为lockObject.wait();会释放锁。
Object lockObject = new Object();
Runnable task1 = () -> {
synchronized (lockObject) {
System.out.println("thread 1 blocked");
LockSupport.park();
System.out.println("thread 1 resumed");
}
};
Thread thread1 = new Thread(task1);
thread1.start();
Runnable task2 = () -> {
System.out.println("thread 2 running ");
synchronized (lockObject) {
System.out.println("thread 2 get lock");
LockSupport.unpark(thread1);
}
};
Thread thread2 = new Thread(task2);
thread2.start();
Run Code Online (Sandbox Code Playgroud)
但是,如果这样使用LockSupport.park/unpark,则会导致死锁。因为 thread1 不会通过使用LockSupport.park. 因此,thread1 无法恢复。
所以要小心,除了阻塞线程之外,它们还有不同的行为。而实际上,还有一些类我们可以方便地使用它来协调多线程环境,比如CountDownLatch, Semaphore, ReentrantLock
| 归档时间: |
|
| 查看次数: |
9403 次 |
| 最近记录: |