【简单多线程问题】3个线程分别打印5次A、B、C,打印顺序为ABC...

Yizhinailu 2020-04-15 11:59:56
我的问题如下:
为什么run()方法中的判断语句是getCount()<13?
从输出结果可以看出,程序最后到了count值为15的时候才结束。但是count值从13开始,run()方法就不会被调用了才对啊。
还是说这样的运行结果和wait()及notifyAll()方法的使用有关,有大神能解释一下吗?

一、测试类:
public class Test {
public static void main(String[] args) {

//创建一个PrintCopy类的对象
PrintCopy pc=new PrintCopy();

//将PrintCopy类的对象作为参数传给一个Print对象
Print print=new Print(pc);

//新建3个线程,并同时取名为"A"、"B"、"C"
Thread t1=new Thread(print,"A");
Thread t2=new Thread(print,"B");
Thread t3=new Thread(print,"C");

//启动线程
t1.start();
t2.start();
t3.start();
}

}

二、打印类:
public class PrintCopy
{
private int flag=1;
private int count=0;

public int getCount() {
return count;
}

public synchronized void printA() {
while(flag!=1) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
flag=2;
count++;
System.out.print(count);
notifyAll();
}

public synchronized void printB() {
while(flag!=2) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
flag=3;
count++;
System.out.print(count);
notifyAll();
}

public synchronized void printC() {
while(flag!=3) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
flag=1;
count++;
System.out.print(count);
notifyAll();
}

}

class Print implements Runnable{
private PrintCopy pc;
public Print(PrintCopy pc) {
this.pc=pc;
}
public void run() {
//控制打印次数
while(pc.getCount()<13) {
if(Thread.currentThread().getName().equals("A")) {
pc.printA();
}
else if(Thread.currentThread().getName().equals("B")) {
pc.printB();
}
else if(Thread.currentThread().getName().equals("C")) {
pc.printC();
}
}
}
}
三、打印结果
A1B2C3A4B5C6A7B8C9A10B11C12A13B14C15
...全文
610 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39936465 2020-04-17
  • 打赏
  • 举报
回复
引用 4 楼 Yizhinailu 的回复:
我的想法和你是一样的,但是看到楼上那位兄弟的解释,就感觉有点难懂。 运行了很多次,它最后都是在15这里停止的。
因为执行的速度原因从wait()到count++ ,前面还有2句语句要执行,而run()里面因为if else嵌套,所以唤醒语句以后马上会执行getCount()<13,所以一般正常情况就不会发生count次序被打乱的情况。
Yizhinailu 2020-04-16
  • 打赏
  • 举报
回复
我的想法和你是一样的,但是看到楼上那位兄弟的解释,就感觉有点难懂。
运行了很多次,它最后都是在15这里停止的。
辉酱OvO 2020-04-16
  • 打赏
  • 举报
回复
首先,你要知道,有三个线程(不算主线程和gc的话),分别是ABC 当count=12时,刚刚打印完c12,从此时开始分析while(pc.getCount()<13) 对于B线程(运行pc.printB()方法,卡死在wait()) 对于C线程(运行pc.printC()方法,卡死在wait()) 对于A线程(运行pc.printA()方法,此时flag=1,count++,打印A13,flag置为2,最后notifyAll()) 此时while(pc.getCount()<13)不成立,任何一个线程走到这里都会结束。但是BC线程此时刚刚唤醒,在wait的代码处醒来,因此还会打印B14,C15,等执行完pc.printB(),pc.printC(),才会走到while判断count是否小于13,当然此时都不成立,所以也会终止。 不过我感觉,这样子的话,不一定保证能输出到15吧,13,14,15都有停止的可能,你可以多运行几次试试看
辉酱OvO 2020-04-16
  • 打赏
  • 举报
回复
引用 4 楼 Yizhinailu 的回复:
我的想法和你是一样的,但是看到楼上那位兄弟的解释,就感觉有点难懂。 运行了很多次,它最后都是在15这里停止的。
你可以尝试一下,把你run方法中的B,C线程部分在执行完print以后sleep一会,看看打印结果会不会存在不同
YangjulongTrue 2020-04-15
  • 打赏
  • 举报
回复
因为你自旋的时候没有判断 count
qq_39936465 2020-04-15
  • 打赏
  • 举报
回复
引用 楼主 Yizhinailu 的回复:
我的问题如下: 为什么run()方法中的判断语句是getCount()<13? 从输出结果可以看出,程序最后到了count值为15的时候才结束。但是count值从13开始,run()方法就不会被调用了才对啊。 还是说这样的运行结果和wait()及notifyAll()方法的使用有关,有大神能解释一下吗?
因为printA,printB,printC是 并行且加锁的,所以线程A判断的count其实就是上轮A时执行的count的值,同理B,C。也就说最后1轮A线程getCount值为10然后进入等待唤醒,B线程getCount值为11然后进入等待唤醒,C线程getCount为值12然后进入等待唤醒。下轮A count变13跳出循环,B count变14后跳出循环,C count变15后跳出循环。
一、 内容概要 本资源提供了一个完整的“金属板材压弯成型”非线性仿真案例,基于ABAQUS/Explicit或Standard求解器完成。案例精确模拟了模具(凸模、凹模)与金属板材之间的接触、压合过程,直至板材发生塑性弯曲成型。 模型特点:包含完整的模具-工件装配体,定义了刚体约束、通用接触(或面面接触)及摩擦系数。 材料定义:金属板材采用弹塑性材料模型,定义了完整的屈服强度、塑性应变等真实应力-应变数据。 关键结果:提供了成型过程中的板材应力(Mises应力)、塑性应变(PE)、厚度变化​ 云图,以及模具受力(接触力)曲线,完整再现了压弯工艺的力学状态。 二、 适用人群 CAE工程师/工艺工程师:从事钣金冲压、模具设计、金属成型工艺分析与优化的专业人员。 高校师生:学习ABAQUS非线性分析、金属塑性成形理论,或从事相关课题研究的硕士/博士生。 结构设计工程师:需要评估钣金件可制造性(DFM)或预测成型回弹的设计人员。 三、 使用场景及目标 学习目标: 掌握在ABAQUS中设置金属塑性成形仿真的全流程,包括材料定义、复杂接触设置、边界条件与载荷步。 学习如何调试和分析大变形、非线性接触问题的收敛性技巧。 理解如何通过仿真预测成型缺陷(如减薄、破裂、回弹),并与理论或实验进行对比验证。 应用价值:本案例的建模方法与分析思路可直接应用于汽车覆盖件、电器外壳、结构件等钣金产品的冲压工艺开发与模具设计优化,减少试模成本。 四、 其他说明 资源包内包含参数化的INP文件、CAE模型文件、材料数据参考及一份简要的操作要点说明文档。INP文件便于用户直接修改关键参数(如压边力、摩擦系数、行程)进行自主研究。 建议使用ABAQUS 2022或更高版本打开。显式动力学分析(如用Explicit)对计算资源有一定要求。 本案例为教学与工程参考目的提供,用户可基于此框架进行拓展,应用于V型弯曲

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧