通俗来讲:
等待/通知机制在我们生活中很常见,一个形象的例子就是厨师和服务员之间就存在等待/通知机制。
使用专业术语讲:
等待/通知机制,是指线程A调用了对象O的wait()方法进入等待状态,而线程B调用了对象O的notify()/notifyAll()方法,线程A收到通知后退出等待队列,进入可运行状态,进而执行后续操作。上述两个线程通过对象O来完成交互,而对象上的wait()方法和notify()/notifyAll()方法的关系就如同开关信号一样,用来完成等待方和通知方之间的交互工作。
通过一道面试题就能完全明白wait/notify机制。
问题:写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印结果为12A34B...5152Z
class Print {
private int flag = 1;//信号量。当值为1时打印数字,当值为2时打印字母
private int count = 1;
public synchronized void printNum() {
if (flag != 1) {
//打印数字
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(2 * count - 1);
System.out.print(2 * count);
flag = 2;
notify();
}
public synchronized void printChar() {
if (flag != 2) {
//打印字母
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print((char) (count - 1 + 'A'));
count++;//当一轮循环打印完之后,计数器加1
flag = 1;
notify();
}
}
public class Test {
public static void main(String[] args) {
Print print = new Print();
new Thread(() -> {
for (int i = 0; i < 26; i++) {
print.printNum();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 26; i++) {
print.printChar();
}
}).start();
}
}
Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”
notify/notifyAll的执行只是唤醒沉睡的线程,而不会立即释放锁,必须执行完notify()方法所在的synchronized代码块后才释放。所以在编程中,尽量在使用了notify/notifyAll()后立即退出临界区。
每个线程执行时都具有一定的优先级,优先级高的线程获得较多的执行机会,而优先级低的线程则获得较少的执行机会。每个线程默认的优先级都与创建它的父线程的优先级相同。Thread类提供了setPriority(int newPriority)来设置指定线程的优先级,提供了getPriority()来返回指定线程的优先级。
JAVA提供了10个优先级级别,但这些优先级需要操作系统支持。不同的操作系统上的优先级并不相同,而且也不能很好的和JAVA的10个优先级对应,比如:Windows 2000仅提供了7个优先级。因此,写代码的时候应该尽量避免直接为线程指定优先级,而应该使用MAX_PRIORITY、MIN_PRIORITY、NORM_PRIORITY这三个静态常量来设置优先级,这样才能保证程序有最好的可移植性。
Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常。
concurrent包是基于AQS(AbstractQueuedSynchronizer)框架的,AQS框架借助于两个类:
LockSupport.park()和LockSupport.unpark(Thread thread)调用的是Unsafe中的native代码。
有关AQS,可以查看笔者之前的博客,快速了解基于AQS实现的Java并发工具类
与Object类的wait/notify机制相比,park/unpark有两个优点:
在Linux系统下,是用的Posix线程库pthread中的mutex(互斥量),condition(条件变量)来实现的。 mutex和condition保护了一个_counter的变量,当park时,这个变量被设置为0,当unpark时,这个变量被设置为1。
更多内容,欢迎关注微信公众号:全菜工程师小辉~
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有