题目可以考的是多线程的互斥与通信问题
思想:
1.第一步,我们先写两个线程,保证两个线程互斥,既相互不干扰的情况下,执行代码,大白话就是,子线程执行代码的时候,主线程别来干扰,主线程执行代码的时候,子线程别来干扰
2.第二步,在两个线程互不干扰的情况,通过waite和notify再去设置线程的执行顺序
互斥不理解的可以先看:https://blog.csdn.net/u010452388/article/details/80626919
第一步:实现互斥
代码
synchronized主要作用就是让两个代码拿用同一个锁,谁拿到锁,谁就可以执行,其他线程在外面等着,由于CPU执行的时候是随机的,所以下面代码只能保证互斥效果
public class ThreadCommunication {
public static void main(String[] args) {
final Bussiness buss = new Bussiness();
// 子线程
new Thread(new Runnable() {
@Override
public void run() {
//循环50次
for (int i = 1; i <= 50; i++) {
buss.sub(i);
}
}
}).start();
// 主线程循环50次
for (int i = 1; i <= 50; i++) {
buss.main(i);
}
}
}
class Bussiness {
//子线程方法
public synchronized void sub(int loopTime) {
//如果运行到这,说明beShouldSub为true,既是子线程执行
for (int i = 1; i <= 10; i++) {
System.out.println("sub thread sequence of " + i + ",loop of " + loopTime);
}
}
//主线程方法
public synchronized void main(int loopTime) {
//如果运行到这,说明beShouldSub为flase,既是主线程执行
for (int i = 1; i <= 100; i++) {
System.out.println("main thread sequence of " + i + ",loop of " + loopTime);
}
}
}
结果
从下面结果,可以看出,主线程执行的时候,子线程没有干扰;子线程执行的时候,主线程也没有干扰,从而达到了互斥的效果
第二步:实现通信
代码
只需要修改Bussindess下的sub方法和main方法即可,代码如下:
设计思想:
1.设定一个标识,这里我们设置了一个布尔型变量beShouldSub ,为true则子线程执行,为false则主线程执行
2.设定执行顺序,先让子线程执行,执行完了后,将beShouldSub 设置为false,后面让主线程执行,主线程执行完成后,beShouldSub 设置为true,后面再让子线程执行,如此往复循环
大白话的意思,就是子线程开始执行,执行完之后,和主线程说,喂,醒醒,该你执行了,然后主线程执行,执行完了对子线程说,喂,醒醒,该你执行了,就这样,子线程和主线程相互和谐的你执行一次,我执行一次
class Bussiness {
private boolean beShouldSub = true;
//子线程方法
public synchronized void sub(int loopTime) {
// 如果beShouldSub为false,说明应该是主线程执行
if (!beShouldSub) {
try {
// 这个时候让子线程睡眠等待,并释放锁
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果运行到这,说明beShouldSub为true,既是子线程执行
for (int i = 1; i <= 10; i++) {
System.out.println("sub thread sequence of " + i + ",loop of " + loopTime);
}
beShouldSub = false;
//这个时候叫醒主线程去执行
this.notify();
}
//主线程方法
public synchronized void main(int loopTime) {
// 如果beShouldSub为true,说明应该是子线程执行,则主线程需要等待
if(beShouldSub){
try {
//这个时候让main线程睡眠等待,并释放锁
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//如果运行到这,说明beShouldSub为flase,既是主线程执行
for (int i = 1; i <= 100; i++) {
System.out.println("main thread sequence of " + i + ",loop of " + loopTime);
}
beShouldSub=true;
//这个时候叫醒子线程去执行
this.notify();
}
}
结果:
从下面结果看,我们实现了效果