一、是什么
1、概念:
LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。其中里面的part()和uppart()方法的作用分别是阻塞线程和接触线程。
2、位置
3、wait/notify、await/signal的加强版
4、三种线程唤醒的方法
1、使用Object中的wait方法让线程等待,使用notify进行唤醒。
1.wait和notify方法必须要在锁块(Synchronized中)里面成对出现使用。。
2.先wait后notify才行。
2、使用JUC包下condition中的await方法使线程等待,signal方法唤醒
1.await和signal方法必须要在锁块(Lock中)里面成对出现使用。。
2.先await后signal才行。
public class LockSupportDemo {
static Object object = new Object();
static Lock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
public static void main(String[] args) {
new Thread(() -> {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "\t" + "-------Come in");
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t" + "------被唤醒");
}finally {
lock.unlock();
}
}, "A").start();
new Thread(() -> {
lock.lock();
try {
condition.signal();
System.out.println(Thread.currentThread().getName() + "\t" + "------通知");
}finally {
lock.unlock();
}
}, "B").start();
}
private static void synchronizedObject() {
new Thread(() -> {
synchronized (object) {
System.out.println(Thread.currentThread().getName() + "\t" + "-------Come in");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t" + "------被唤醒");
}
}, "A").start();
new Thread(() -> {
synchronized (object) {
object.notify();
System.out.println(Thread.currentThread().getName() + "\t" + "------通知");
}
}, "B").start();
}
}
3、LockSupport类中的方法可以阻塞当前线程和唤醒指定被阻塞的线程
5、术语
LockSupport类使用了一种名为permit(许可)的概念来阻塞和唤醒线程的功能,每个线程都有一个许可。permit只有两个值:0或1.默认是0。可以把许可看做是一种(0,1)信号量(semaphore)。但与信号量不同的是,许可累加上线是1。
二、主要方法
1、park()/park(Object blocker):阻塞当前线程/阻塞传入的具体线程
permit默认是0,所以一开始调用park()方法,当前线程就会阻塞,
直到别的线程将当前线程的permit置为1时,park()才会被唤醒,
然后会将permit再次设置为0并返回。
2、unpark(Thread thread):唤醒处于阻塞状态的具体线程
Thread a = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "-------Come in");
LockSupport.park();//被阻塞,等待通知等待放行,他通过需要许可证。如果先执行
// LockSupport.unpark(a);方法,这个方法相当于没有执行
System.out.println(Thread.currentThread().getName() + "\t" + "------被唤醒");
}, "A");
a.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread b = new Thread(() -> {
LockSupport.unpark(a);//给A线程许可证
System.out.println(Thread.currentThread().getName() + "\t" + "------通知");
}, "B");
b.start();
}
3、原理
三、面试题