【简单多线程问题】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
...全文
620 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后跳出循环。
内容概要:本文系统研究了多轴同步轨迹规划中的三种主流算法——7段S型、5段S型和多轴梯形轨迹规划,重点阐述其设计思路、运动特性及适用场景。三类算法均采用“独立预规划—基准轴选取—参数比例缩放”的统一同步策略,确保多轴同时启停。7段S型通过加加速度约束实现最优平滑性,适用于超精密设备;5段S型在保留加加速度控制的基础上简化结构,兼顾平滑性与计算效率,广泛应用于通用工业自动化场景;梯形轨迹以三段式结构(加速-匀速-减速)实现极简计算与快速响应,适合低成本、高效率应用。文章对比分析了三者的平滑性、控制复杂度、计算量及工程适用性,为不同精度与成本需求下的系统选型提供理论依据,并展望了未来向智能化、自适应化和轻量化发展的趋势。; 适合人群:具备一定自动化控制或机械电子工程背景,从事运动控制算法研发、工业机器人开发或数控系统设计的研发人员及高校研究生。; 使用场景及目标:①为工业机器人、数控机床、自动化装配线等多轴协同系统提供轨迹规划方案选型依据;②帮助开发者理解不同轨迹算法在平滑性、响应速度与实现难度之间的权衡关系,指导实际工程中控制性能与成本的平衡设计; 阅读建议:此资源侧重于多轴同步控制的工程实现逻辑,建议结合Matlab仿真代码进行实践验证,重点关注各算法的参数缩放机制与同步生成过程,通过对比仿真结果深入掌握其动态特性和应用场景差异。
内容概要:本文基于Matlab代码实现,系统复现并对比了四种先进控制器——深度确定性策略梯度强化学习(DDPG-RL)与线性二调节器(LQR)结合、Bryson规则与LQR结合、LQR与比例微分(PD)控制结合,以及基础LQR控制,在无人机(UAV)集群轨迹跟踪任务中的性能表现。研究聚焦于控制器在复杂动态环境下的轨迹跟踪精度、响应速度、抗干扰能力及系统稳定性,通过仿真实验定量分析各方法的优劣。DDPG-RL+LQR利用强化学习自适应优化控制策略,具备较强的环境适应性;Bryson规则+LQR通过最优控制理论整定参数,提升动态响应;LQR+PD则增强了系统的阻尼特性以抑制振荡;基础LQR作为基准方法,体现经典最优控制性能。该研究源自一区TOP期刊论文复现,具有较高的学术参考价值。; 适合人群:具备自动控制理论基础、强化学习初步知识及Matlab编程能力,从事无人机控制、智能算法应用或相关领域研究的研究生、科研人员及工程师(工作年限1-3年为佳);; 使用场景及目标:① 掌握先进控制策略在多智能体系统中的建模与仿真方法;② 对比分析传统最优控制与智能控制融合方案在轨迹跟踪中的性能差异;③ 为无人机集群协同控制、自主导航系统设计提供算法选型依据和技术验证手段; 阅读建议:建议结合提供的Matlab代码逐模块调试运行,重点关注控制器设计、状态反馈机制与性能指标计算部分,深入理解算法实现细节,并可通过修改环境参数或引入外部扰动进一步拓展实验,以全面掌握各控制器的适应边界与优化潜力。
内容概要:本文基于强化学习与优化反步法,研究水面舰艇在复杂海洋环境下的自适应轨迹跟踪控制问题。通过构建非线性动力学模型,结合强化学习的在线学习能力与反步法的系统化控制设计优势,提出一种能够应对模型不确定性、外部干扰及动态环境变化的鲁棒自适应控制策略。研究采用Lyapunov稳定性理论保证系统收敛性,并通过Matlab仿真验证所提方法在轨迹跟踪精度、抗干扰能力及自适应调节性能方面的优越表现,复现了一区顶级期刊(IEEE Transactions)级别的研究成果,具有较强的学术参考价值和技术可行性。; 适合人群:具备自动控制理论、非线性系统分析基础,熟悉Matlab/Simulink仿真环境,从事船舶控制、智能控制、强化学习应用等方向的研究生、科研人员及工程技术人员(建议具备1年以上相关研究经验)。; 使用场景及目标:① 学习并掌握强化学习与反步控制相结合的设计思路与实现方法;② 复现高水平期刊论文中的先进控制算法;③ 应用于水面无人艇(USV)、自动驾驶船舶等智能航海装备的轨迹跟踪控制系统开发与优化;④ 为非线性系统自适应控制、智能控制算法融合提供技术借鉴。; 阅读建议:建议结合反步法、强化学习、Lyapunov稳定性等基础知识同步学习,重点理解控制器设计的递推过程与自适应律构建机制,并动手调试Matlab代码以加深对算法细节和参数调节规律的理解。

62,623

社区成员

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

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