首页 技术 正文
技术 2022年11月15日
0 收藏 834 点赞 3,339 浏览 1881 个字

本文章内容整理自:张孝祥_Java多线程与并发库高级应用视频教程。

有些时候,线程间需要传递消息,比如下面这道面试题:

子线程循环10次,然后主线程循环100次,然后又回到子线程循环50次,然后再回到主线程循环100次。以上过程一共循环50次。

通过分析可以知道,主线程和子线程是互斥的,即主线程和子线程不能同时执行。此外,主线程和子线程有固定的轮换关系,主线程执行完后,必须是子线程接着执行,然后又是主线程执行。

要达到这种效果,光是线程互斥是不够的。因为有可能主线程执行完之后,cpu又将执行的权利分配给主线程,这样主线程又会执行一遍。要让两个线程交替执行,就需要这两个线程间可以通信。主线程执行完了,就通知子线程执行。子线程执行完了,再通知主线程执行。如此往复。

像这种线程间协作的情况,就叫线程同步。

下面直接贴出代码

package com.sky.thread;public class Test4 {
private boolean mainOrSub = true;//线程间通信的变量
public static void main(String[] args) {
final Test4 t4 = new Test4();
new Thread(new Runnable() { @Override
public void run() {
//执行50次主线程
for (int i = 0; i < 50; i++) {
try {
t4.mainThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() { @Override
public void run() {
//执行50次子线程
for (int i = 0; i < 50; i++) {
try {
t4.subThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
}).start();
} //主线程执行的方法
public synchronized void mainThread() throws InterruptedException {
//判断是否轮到自己执行
//此处用while代替if,可以提高程序的健壮性。
//线程有时会自己醒来,如果用if,当线程自己醒来后会接着执行this.wait()后面的代码,这样是不对的。
//而使用while,线程自己醒来后,根据while的规则,会再判断一次mainOrSub的值。
if (mainOrSub) {
//如果mainOrSub是true,表示不该自己执行。于是把线程挂起。
this.wait();
}
for (int i = 0; i < 100; i++) {
System.out.println("main-"+Thread.currentThread().getName() + ":" + i);
}
//执行完毕后更改mainOrSub的状态,并唤醒其他线程
mainOrSub = true;
this.notify();
} //子线程执行的方法
public synchronized void subThread() throws InterruptedException {
//判断是否轮到自己执行
while (!mainOrSub) {
//如果mainOrSub是false,表示不该自己执行。于是把线程挂起。
this.wait();
}
for (int i = 0; i < 10; i++) {
System.out.println("sub-"+Thread.currentThread().getName() + ":" + i);
}
//执行完毕后更改mainOrSub的状态,并唤醒其他线程
mainOrSub = false;
this.notify();
}
}

在上面的代码中,创建了一个变量mainOrSub用于线程间通信。通过mainOrSub的值来控制线程的交替执行。

可见,使用多个线程都可以访问到的变量,就可以实现线程间通信。

还有一点值得注意,在判断mainOrSub的值时,用while代替了if,这样可以提高程序的健壮性。因为使用wait()挂起的线程有时会自己醒来。如果用if,当线程自己醒来后会接着执行this.wait()后面的代码,而此时并不该它执行。如果用while,线程自己醒来后,根据while的规则,会再判断一次mainOrSub的值,这样就可以保证线程完全依照mainOrSub的值来决定要不要执行。

经验:要用到共同数据(包括同步锁)的若干个方法应该归在同一个类身上,这种设计体现了高内聚和程序的健壮性。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,086
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,561
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,410
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,183
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,820
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,903