共计 3074 个字符,预计需要花费 8 分钟才能阅读完成。
突击并发编程 JUC 系列演示代码地址:
https://github.com/mtcarpenter/JavaTutorial
Locksupport
JDK
中的 rt.jar
包外面的 LockSupport
是个工具类,当须要阻塞或唤醒一个线程的时候,都能够应用 LockSupport
工具类来实现相应工作。LockSupport
定义了一组的公共静态方法,这些办法提供了最根本的线程阻塞和唤醒性能,而 LockSupport
也成为构建同步组件的根底工具。LockSupport
定义了一组以 park
结尾的办法用来阻塞以后线程,以及 unpark(Thread thread)
办法来唤醒一个被阻塞的线程。上面介绍 LockSupport
中的几个次要函数。
void park()
: 阻塞以后线程,如果调用unpark(Thread thread)
办法或者以后线程被中断,能力从park()
办法返回。void parkNanos(long nanos)
: 阻塞以后线程,最长不超过nanos
纳秒,返回条件在park()
的根底上减少了超时返回。void parkUntil(long deadline)
: 阻塞以后线程,晓得 deadline 工夫(从 1970 年开始到 deadline 工夫的毫秒数)。void unpark(Thread thread)
: 唤醒处于阻塞状态的线程 thread。void park(Object blocker)
: 阻塞以后线程,blocker 用来标识以后线程在期待的对象。parkNanos(Object blocker, long nanos)
: 比void park(Object blocker)
减少一个超时工夫。parkUntil(Object blocker, long deadline)
: 比void parkUntil(long deadline)
多一个阻塞以后对象。
Locksupport 案例上手
public class LockExample4 {public static void main(String[] args) throws Exception {Thread t1 = new Thread(new Runnable() {
@Override
public void run() {System.out.println(Thread.currentThread().getName() + "开始阻塞");
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "阻塞曾经被放开");
}
}, "t1");
t1.start();
TimeUnit.SECONDS.sleep(3);
new Thread(new Runnable() {
@Override
public void run() {System.out.println(Thread.currentThread().getName() + "开始");
LockSupport.unpark(t1);
System.out.println(Thread.currentThread().getName() +"阻塞曾经被放开");
}
}, "t2").start();}
}
运行后果:
t1 开始阻塞
t2 开始
t2 阻塞曾经被放开
t1 阻塞曾经被放开
Condition
任意一个 Java 对象,都领有一组监视器办法(定义在 java.lang.Object
上),次要包含 wait()
、wait(long timeout)
、notify()
以及 notifyAll()
办法,这些办法与 synchronized
同步关键字配合,能够实现期待 / 告诉模式。Condition
接口也提供了相似 Object
的监视器办法,与 Lock
配合能够实现期待 / 告诉模式,然而这两者在应用形式以及性能个性上还是有差异的。
Condition 办法阐明
void await() throws InterruptedException
: 以后线程进入期待状态直到被告诉(signal)或中断,以后线程将进入运行状态且从 await() 办法 返回的状况。包含:
-
其余线程调用该
Condition
的signal()
或signalAll()
办法,而以后线程被选中唤醒- 其余线程(调用
Interrupt()
办法)中断以后线程 - 如果以后期待线程从
await()
办法返回,那么表明该线程曾经获取了Condition
对象所对应的锁
- 其余线程(调用
void awaitUninterruptibly()
: 以后线程进入期待状态被告诉,从办法返回名称上能够看出该办法对中断不敏感long awaitNanos(long nanosTimeout)
: 以后线程进入期待状态直到被告诉,中断或者超时。返回值示意残余的工夫,如果在 nanosTimeout 纳秒之前被唤醒,那么返回值就是(nanosTimeout- 理论耗时)。如果返回 0 或者正数,那么能够认定曾经超时了boolean awaitUntil(Date deadline)
: 以后线程进入期待状态晓得被告诉、中断或者到某一个工夫。如果没有到指定工夫就被告诉,办法返回 true,否则,示意到了指定工夫,办法返回 false。void signal()
: 唤醒一个期待在Condition
上的线程,该线程从期待办法返回前必须取得与Condition
相干的锁void signalAll()
: 唤醒所有期待在Condition
上的线程,可能从期待办法返回的线程必须取得与Condition
相干的锁
Condition 案例上手
public class LockExample5 {public static void main(String[] args) throws Exception {Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {lock.lock();
try {System.out.println(Thread.currentThread().getName() + "开始阻塞");
condition.await();
System.out.println(Thread.currentThread().getName() + "阻塞曾经被放开");
} catch (InterruptedException e) { } finally {lock.unlock();
}
}
}, "t1");
t1.start();
TimeUnit.SECONDS.sleep(3);
new Thread(new Runnable() {
@Override
public void run() {lock.lock();
try {System.out.println(Thread.currentThread().getName() + "开始阻塞");
condition.signalAll();
System.out.println(Thread.currentThread().getName() + "阻塞曾经被放开");
} finally {lock.unlock();
}
}
}, "t2").start();}
}
运行后果:
t1 开始阻塞
t2 开始阻塞
t2 阻塞曾经被放开
t1 阻塞曾经被放开
欢送关注公众号 山间木匠, 我是小春哥,从事 Java 后端开发,会一点前端、通过继续输入系列技术文章以文会友,如果本文能为您提供帮忙,欢送大家关注、点赞、分享反对,_咱们下期再见!_