深入浅出Java多线程-方法join

本文深入探讨Java多线程中的Join方法原理及应用,解析其内部实现机制,并通过示例代码演示如何同步线程执行。

对于Java开发人员,多线程应该是必须熟练应用的知识点,特别是开发基于Java语言的产品。本文将深入浅出的表述Java多线程的知识点,在后续的系列里将侧重于Java5由Doug Lea教授提供的Concurrent并行包的设计思想以及具体实现与应用。
如 何才能深入浅出呢,我的理解是带着问题,而不是泛泛的看。所以该系列基本以解决问题为主,当然我也非常希望读者能够提出更好的解决问题的方案以及提出更多 的问题。由于水平有限,如果有什么错误之处,请大家提出,共同讨论,总之,我希望通过该系列我们能够深入理解Java多线程来解决我们实际开发的问题。
作为开发人员,我想没有必要讨论多线程的基础知识,比如什么是线程? 如何创建等 ,这些知识点是可以通过书本和Google获得的。本系列主要是如何理深入解多线程来帮助我们平时的开发,比如线程池如何实现? 如何应用锁等。
(1)方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答。
自 从接触Java多线程,一直对Join理解不了。JDK是这样说的:join public final void join(long millis)throws InterruptedException Waits at most millis milliseconds for this thread to die。 A timeout of 0 means to wait forever。大家能理解吗? 字面意思是等待一段时间直到这个线程死亡,我的疑问是那个线程,是它本身的线程还是调用它的线程的,上代码:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http:///
--package concurrentstudy;
/

@author vma
/
public class JoinTest {
public static void main(String【】 args) {
Thread t = new Thread(new RunnableImpl());
t。start();
try {
t。join(1000);
System。out。println("joinFinish");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e。printStackTrace();



class RunnableImpl implements Runnable {
@Override
public void run() {
try {
System。out。println("Begin sleep");
Thread。sleep(1000);
System。out。println("End sleep");
} catch (InterruptedException e) {
e。printStackTrace();



结果是:
Begin sleep
End sleep
joinFinish
明白了吧,当main线程调用t。join时,main线程等待t线程,等待时间是1000,如果t线程Sleep 2000呢
public void run() {
try {
System。out。println("Begin sleep");
// Thread。sleep(1000);
Thread。sleep(2000);
System。out。println("End sleep");
} catch (InterruptedException e) {
e。printStackTrace();


结果是:
Begin sleep
joinFinish
End sleep
main线程只等1000毫秒,不管T什么时候结束,如果是t。join()呢, 看代码:
public final void join() throws InterruptedException {
join(0);

就是说如果是t。join() = t。join(0) 0JDK这样说的 A timeout of 0 means to wait forever 字面意思是永远等待,是这样吗?
其实是等到t结束后。
这个是怎么实现的吗? 看JDK代码:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http:///
--> /
Waits at most millis milliseconds for this thread to
die。 A timeout of 0 means to wait forever。

@param millis the time to wait in milliseconds。
@exception InterruptedException if any thread has interrupted
the current thread。 The interrupted status of the
current thread is cleared when this exception is thrown。
/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System。currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");

if (millis == 0) {
while (isAlive()) {
wait(0);

} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;

wait(delay);
now = System。currentTimeMillis() - base;


}其实Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t。join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程,比如退出后。
这就意味着main 线程调用t。join时,必须能够拿到线程t对象的锁,如果拿不到它是无法wait的,刚开的例子t。join(1000)不是说明了main线程等待1秒,如果在它等待之前,其他线程获取了t对象的锁,它等待时间可不就是1毫秒了。上代码介绍:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http:///
--/
To change this template, choose Tools

Templates
and open the template in the editor。
/
package concurrentstudy;
/

@author vma
/
public class JoinTest {
public static void main(String【】 args) {
Thread t = new Thread(new RunnableImpl());
new ThreadTest(t)。start();
t。start();
try {
t。join();
System。out。println("joinFinish");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e。printStackTrace();



class ThreadTest extends Thread {
Thread thread;
public ThreadTest(Thread thread) {
this。thread = thread;

@Override
public void run() {
holdThreadLock();

public void holdThreadLock() {
synchronized (thread) {
System。out。println("getObjectLock");
try {
Thread。sleep(9000);
} catch (InterruptedException ex) {
ex。printStackTrace();

System。out。println("ReleaseObjectLock");



class RunnableImpl implements Runnable {
@Override
public void run() {
try {
System。out。println("Begin sleep");
Thread。sleep(2000);
System。out。println("End sleep");
} catch (InterruptedException e) {
e。printStackTrace();



在 main方法中 通过new ThreadTest(t)。start();实例化ThreadTest 线程对象, 它在holdThreadLock()方法中,通过 synchronized (thread),获取线程对象t的锁,并Sleep(9000)后释放,这就意味着,即使
main方法t。join(1000),等待一秒钟,它必须等待ThreadTest 线程释放t锁后才能进入wait方法中,它实际等待时间是9000+1000 MS
运行结果是:
getObjectLock
Begin sleep
End sleep
ReleaseObjectLock
joinFinish
考试大小结:本节主要深入浅出join及JDK中的实现。

内容概要:本文围绕EKF SLAM(扩展卡尔曼滤波同步定位与地图构建)的性能展开多项对比实验研究,重点分析在稀疏与稠密landmark环境下、预测与更新步骤同时进行与非同时进行的情况下的系统性能差异,并进一步探讨EKF SLAM在有色噪声干扰下的鲁棒性表现。实验考虑了不确定性因素的影响,旨在评估不同条件下算法的定位精度与地图构建质量,为实际应用中EKF SLAM的优化提供依据。文档还提及多智能体系统在遭受DoS攻击下的弹性控制研究,但核心内容聚焦于SLAM算法的性能测试与分析。; 适合人群:具备一定机器人学、状态估计或自动驾驶基础知识的科研人员及工程技术人员,尤其是从事SLAM算法研究或应用开发的硕士、博士研究生和相关领域研发人员。; 使用场景及目标:①用于比较EKF SLAM在不同landmark密度下的性能表现;②分析预测与更新机制同步与否对滤波器稳定性与精度的影响;③评估系统在有色噪声等非理想观测条件下的适应能力,提升实际部署中的可靠性。; 阅读建议:建议结合MATLAB仿真代码进行实验复现,重点关注状态协方差传播、观测更新频率与噪声模型设置等关键环节,深入理解EKF SLAM在复杂环境下的行为特性。稀疏 landmark 与稠密 landmark 下 EKF SLAM 性能对比实验,预测更新同时进行与非同时进行对比 EKF SLAM 性能对比实验,EKF SLAM 在有色噪声下性能实验
内容概要:本文围绕“基于主从博弈的售电商多元零售套餐设计与多级市场购电策略”展开,结合Matlab代码实现,提出了一种适用于电力市场化环境下的售电商优化决策模型。该模型采用主从博弈(Stackelberg Game)理论构建售电商与用户之间的互动关系,售电商作为领导者制定电价套餐策略,用户作为跟随者响应电价并调整用电行为。同时,模型综合考虑售电商在多级电力市场(如日前市场、实时市场)中的【顶级EI复现】基于主从博弈的售电商多元零售套餐设计与多级市场购电策略(Matlab代码实现)购电组合优化,兼顾成本最小化与收益最大化,并引入不确定性因素(如负荷波动、可再生能源出力变化)进行鲁棒或随机优化处理。文中提供了完整的Matlab仿真代码,涵盖博弈建模、优化求解(可能结合YALMIP+CPLEX/Gurobi等工具)、结果可视化等环节,具有较强的可复现性和工程应用价值。; 适合人群:具备一定电力系统基础知识、博弈论初步认知和Matlab编程能力的研究生、科研人员及电力市场从业人员,尤其适合从事电力市场运营、需求响应、售电策略研究的相关人员。; 使用场景及目标:① 掌握主从博弈在电力市场中的建模方法;② 学习售电商如何设计差异化零售套餐以引导用户用电行为;③ 实现多级市场购电成本与风险的协同优化;④ 借助Matlab代码快速复现顶级EI期刊论文成果,支撑科研项目或实际系统开发。; 阅读建议:建议读者结合提供的网盘资源下载完整代码与案例数据,按照文档目录顺序逐步学习,重点关注博弈模型的数学表达与Matlab实现逻辑,同时尝试对目标函数或约束条件进行扩展改进,以深化理解并提升科研创新能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值