频道首页
目录
join唤醒线程原理与c++析构函数有关
收藏
0
@[toc]
在使用 join 方法, 它到底是如何去唤醒线程的呢, 希望这篇文章可以帮助到你解决问题
析构函数简介
析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。
c++的退出线程方法
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
// 省略代码
ensure_join(this); // ensure_join是线程退出时调用(内部会调用notifyAll)
// 省略代码
}
thread.cpp#ensure_join
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "java thread object must exist");
ObjectLocker lock(threadObj, thread); // 创建ObjectLocker(构造函数加锁,析构函数解锁)
thread->clear_pending_exception(); // 清除待处理异常,因为线程准备退出了
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED); // 设置线程状态为 TERMINATED
java_lang_Thread::set_thread(threadObj(), NULL);// 将属性设置为null, 这样 is_alive方法就会返回 false
lock.notify_all(thread); // 唤醒所有关联的重量级锁上等待的线程
thread->clear_pending_exception(); // 清除待处理异常(走到这个地方 ObjectLocker生命周期结束,自动调用析构函数)
}
synchronizer.cpp
在学习 线程通信的时候发现 synchronizer.cpp
这段代码挺有意思的。小伙伴们在学习 wait/notify/notifyAll
肯定会遇到的,故这里演示一下。
ObjectLocker::ObjectLocker(Handle obj, Thread* thread, bool doLock) {
_dolock = doLock;
_thread = thread;
debug_only(if (StrictSafepointChecks) _thread->check_for_valid_safepoint_state(false);)
_obj = obj;
if (_dolock) {
TEVENT (ObjectLocker) ;
ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread);// 构造函数加锁
}
}
ObjectLocker::~ObjectLocker() { // 析构函数(一般用来和构造函数执行相反的动作)
if (_dolock) {
ObjectSynchronizer::fast_exit(_obj(), &_lock, _thread);
}
}
测试析构函数代码
#include <iostream>
using namespace std;
class Test{
public:
void setLength(double length);
double getLength(void);
Test();
~Test();
private:
double length;
};
Test::Test(void) {
cout << "=======begin=======";
}
Test::~Test(void) {
cout << "=======end=========";
}
void Test::setLength(double length) {
length = length;
}
double Test::getLength(void) {
return length;
}
int main() {
Test test;
test.setLength(6.0);
cout << "length: " << test.getLength() << endl;
return 0;
}
`执行如下指令
g++ -o Test Test.cpp
./Test
输出结果
=======begin=======
length: 2.0736e-317
=======end=========
文末总结
以前还不懂为啥用个 join 就能阻塞线程, 然后其他线程跑完 main
线程才会继续走后面的流程, 原来是因为在其他线程退出的时候去调用了析构函数啊。
主页
Git管理
文章
云文档
留言墙
AI文档