c 多线程退出情况下,主线程先退出,子线程会被强制退出吗

主线程中子线程之间的执行顺序
public class Thread1{
&&&&&&&&&&&&&&&&&&&&
public static synchronized void main(String args[]){
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Thread t=new Thread(){
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
public void run(){
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
System.out.print("ping");
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
static synchronized void pong(){
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
System.out.print("pong");
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
是否会输出 pingpong ? 如果不是那输出什么?为什么?
主线程 中 出现子线程 是否子 run 方法结束后 才执行 后续代码
我执行过此代码 是pongping&
这个是我在华为的面试题目,我进了个做华为外包的公司。麻烦您指教指教
这里的"主","子"只是一个幌子!楼主请注意!
在main()方法中,虽然new
一个Thread,但并没有真正启动该线程!真正启动线程应该调用t.start()!此处调用的是t.run(),JVM并不会以线程方式启动线程"t"!
所以此段代码永远不会输出pingpong,只会输出pongping!
==============
当代码中的t.run()变成t.start(),结果如何呢?我们将代码稍微改一点点:
public class Test{
&public static synchronized void main(String
& Thread t=new Thread(){
&& public void run(){
& t.start();
& int i = 0;
& while(i & 50){
System.out.println("&&&A
"+"astate="
+Thread.currentThread().getState()
+" bstate="+t.getState());
Thread.sleep(10);
&& } catch (InterruptedException
&static synchronized void pong(){
& int i = 0;
& while(i & 50){
System.out.println("&&&B
"+"bstate="+Thread.currentThread().getState());
Thread.sleep(10);
&& } catch (InterruptedException
这时我们可以看到,只能等主线程完全执行完毕以后,才会执行线程t.同时我们看到当主线程执行时,线程t的状态一直为BLOCKED(阻塞).
那么为什么主线程执行时,t线程一直被阻塞呢?这就是main方法和pong方法前的synchronized 修饰词在作怪.
首先我们得了解synchronized
修饰词的作用,但了解synchronized的同时,我们还得了解LOCK(锁).JAVA中规定,每个对象有且仅有一个锁,这个锁是JVM自动维护的,不需要显示去定义.
另外synchronized只是在多线程同时工作时起作用.
那么synchronized修饰词就说了,访问我这个方法(或这段代码)必须要单独执行,也就是说,想要执行我,就得把某个东西给锁上,这就是你想执行我的代价.
把某个东西锁上,锁谁呢?前面说了,每个对象都有一把锁啊?那么这个被锁的对象就得根据synchronized修饰的位置而定了.
且只拿你的这段代码来说明:
此Test类有两个static方法,而这两个static方法前都加了synchronized的修饰.如果synchronized加在static方法前,就表明线程在访问这个方法时,会自动锁住此方法"所在类的类对象"(java秉承万物皆对象的宗旨,类本身也不例外).比如main()方法和pong()方法,他们的synchronized就表明在访问它们的时候,会锁住Test.class对象.
好,知道了原理再来理解就很容易啦!
首先主线程来执行入口方法(即main()),但main()前有synchronized关键字,这时候主线程就会给Test.class上锁.然后继续执行,一直很顺利的执行,直到遇见t.start().这个时候,主线程会通过t.start()方法通知JVM:要开一个新线程啦,我已经把它给准备好啦!
然而主线程就只是在这里通知一下而已,它不会等待t线程真正开始,事实上它根本不关心t线程的死活.好啊,JVM收到了通知,就做了一系列准备,要来启动t线程,然后费了九牛二虎之力把它给启动了.t线程也开始执行了.t线程的任务是做什么呢?就是执行pong()方法.当它想执行pong()方法时,发现pong()方法是静态的,而且前面还有synchronized修饰符,它就必须得先给Test.class上锁啊,只有锁住Test.class才能有权力执行pong()方法.结果t线程来锁Test.class对象的时候,发现该对象已经被锁了!原来是前面主线程在执行main()方法时锁住的.那么t线程就只能等啦!于是它就BLOCKED了.
主线程呢,在通知JVM启动t线程之后,它就继续往下执行了,这里我改了代码,会输出50行字符,每输出一行就会休息10毫秒.于是主线程就按照这种方式工作下去.50行字符输出完了,main()方法也就执行完了,于是就将之前锁住的Test.class给开锁了.这时候在一旁等待的t线程发现Test.class解锁啦!于是它立马又将其锁住,开始执行它的pong()方法了.
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。博客分类:
为什么要有中断技术
某些场景,需要强制结束处于冻结状态(sleep,wait)的线程时,立即改变其冻结状态,让其回到阻塞状态,待获取到CPU执行权后,在catch块中改变run()执行标记,实现将线程停止的目的。
interrupt 线程中断技术,实际上就是用强制的方式来改变线程的状态
将处于冻结状态的线程,由冻结状态---&阻塞状态
冻结状态:sleep(time),wait() ,没有执行资格,没有执行权
阻塞状态:具备执行资格,正等待CPU执行权
sleep(time) 必须待时间到才能醒,如果interrupt,则睡眠状态被清除,立即醒;
wait() 由notify()/notifyAll()来唤醒,如果interrupt,则等待状态被清除,不再等待
interruptedException异常
强制将处于冻结状态的线程改变为阻塞状态,使其具备CPU执行资格。
由于这个强制动作破坏了程序预期的执行过程,将抛出interruptedException异常。此时,就需要在catch到interruptedException时,重新对线程的运行环境进行设置。
===================================================================================
如何停止处于冻结状态的线程---使用中断技术
要让线程停止,即让run()执行结束。
通常设置标记来控制线程是否继续执行。
如果多线程都处于了冻结状态,则无法读取标记进行判断,此时就需要使用中断技术,强制解除其冻结状态,回到运行状态去读取新的标记值,达到结束线程的目的!
package com.gc.
不是将线程停止,而是强制解除睡眠或等待状态的线程,将其状态切换到阻塞状态,具备执行资格
当被分配到CPU执行权后,将继续执行catch-InterruptedException块中的代码,此处可以做一些控制:
改变运行环境中的资源,让线程继续执行;
改变标记,控制线程是否继续执行;
public class InterruptThread implements Runnable{
boolean flag =
public void changeFlag() {
public void run() {
synchronized(this) {
while(flag) {
System.out.println(Thread.currentThread().getName()+"---waiting");
//线程处于wait状态,释放锁,让其它线程可以进入
} catch(InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"---interrupted");
//线程被中断,回到阻塞状态,当其获得CPU执行权后,在此处改变多线程执行标记,将其停止!
changeFlag();
System.out.println(Thread.currentThread().getName()+"---"+"over!");
public static void main(String[] args) throws InterruptedException {
InterruptThread runnable = new InterruptThread();
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
t1.start();
t2.start();
//让t1和t2都处于冻结状态
Thread.sleep(10);
t1.interrupt();//解除t1线程的冻结状态,此时t1线程抛出InterruptedException,由catch块捕获,对标记进行改变
t2.interrupt();//解除t2线程的冻结状态,此时t2线程抛出InterruptedException,由catch块捕获,对标记进行改变
浏览: 227039 次
logback配置文件的改动会导致应用重新加载,多改动几次后就 ...
不是可以在log4j中配置以控制台或者文件方式保存日志的?
很棒,正缺这个,非常感谢
[size=x-small][/size]
有,和YAML的格式有关,不知道有没有什么好的YAML格式的验 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'其他回答(1)
你的 catch 试试为空
园豆:12845
&&&您需要以后才能回答,未注册用户请先。& & & & 额,好吧,这是个标题党,其实所有的线程都是平级的,根本不存在主线程和子线程。下文所述为了方便,将在main函数中的线程看做主线程,其它线程看成子线程,特此说明。先考虑以下代码:
#include &pthread.h&
#include &stdio.h&
#include &unistd.h&
void* thrd_start_routine(void* v)
sleep(10);
printf(&created thread\n&);
int main()
pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
printf(&main thread\n&);
运行,结果是5s休眠后,打印“main thread&;程序退出
之前误认为线程和进程一样,主线程退出,子线程退出。再考虑以下代码;
#include &pthread.h&
#include &stdio.h&
#include &unistd.h&
void* thrd_start_routine(void* v)
sleep(10);
printf(&created thread\n&);
int main()
pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
printf(&main thread\n&);
pthread_exit(NULL);
printf(&main exit\n&);
结果输出5s后输出 created thread;注意u,此处的main exit并不输出
相较于上一个程序,只加了一句 pthread_exit(NULL);
之前一个程序是在打印主线程之后,程序return,间接调用了exit()函数,因为一个线程调用exit函数,导致整个进程的退出,系统回收所有的资源,当然所有 的线程都退出了。再第二个程序中;找到以下资料:
When you program with POSIX Threads API, there is one thing about pthread_exit() that you may ignore for mistake. In subroutines that complete normally,
there is nothing special you have to do unless you want to pass a return code back using pthread_exit(). The completion won't affect the other threads which were created by the main thread of this subroutine. However, in main(), when the code has been executed
to the end, there could leave a choice for you. If you want to kill all the threads that main() created before, you can dispense with calling any functions.&But
if you want to keep the process and all the other threads except for the main thread alive after the exit of main(), then you can call pthread_exit() to realize it. And any files opened inside the main thread will remain open after its termination.
在主线程退出时,要想系统并不回收进程的所有资源,可以调用pthread_exit();然后等其他线程终止退出。
然后考察一到面试题:
我的代码如下:
#include &iostream&
#include &pthread.h&
#include &stdlib.h&
int flag=0;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
void* thread1(void *var);
void* thread2(void *var);
int main()
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread1,&tid2);
pthread_create(&tid2,NULL,thread2,NULL);
pthread_cond_wait(&cond,&mutex);
cout&&&init thread exit&&&
pthread_exit(NULL);
void* thread1(void *var)
// pthread_detach(pthread_self());
pthread_mutex_lock(&mutex);
if(flag==2)
pthread_cond_signal(&cond);
cout&&&this is thread1&&&
pthread_mutex_unlock(&mutex);
pthread_join(*(pthread_t *)var,NULL);
cout&&&thread1 exit&&&
void* thread2(void *var)
// pthread_detach(pthread_self());
pthread_mutex_lock(&mutex);
if(flag==1)
pthread_cond_signal(&cond);
cout&&&this is thread2&&&
pthread_mutex_unlock(&mutex);
cout&&&thread2 exit&&&
如代码所示,如果此处在main函数中没有pthread_exit(),那在flag由1变2或者由2变1时,其它线程通知main函数中的线程,将使得主进程直接退出,其它另外的线程就终止了,可能等不到打印线程exit语句。
本文已收录于以下专栏:
相关文章推荐
原来的moveit实在Ubuntu12.04上安装的,ros版本是hydro,后来重装电脑,系统变成了16.04,对应的ros版本为Kinetic。重装的时候,又重新记录了一下安装步骤。
我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下。
1、  主线程等待新线程先结束退出,主线程后退出。正常执行。
实例代码:...
1、进程中线程之间的关系
线程不像进程,一个进程中的线程之间是没有父子之分的,都是平级关系。即线程都是一样的, 退出了一个不会影响另外一个。
但是所谓的&主线程&main,其入口代码是类似这样的方...
我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下。
1、  主线程等待新线程先结束退出,主线程后退出。正常执行。
实例代码:
今天写线程,再网页上找了些关闭线程的栗子,给大家整理一下~~~
     多线程程序的开发中,启动了多个线程的程序在关闭的时候却出现了问题,如果程序退出的时候不关闭线程,那么线程就会一直的存在,但是...
* 四个线程,a b c d ,共享一个变量 i ab 为加线程, cd 为减线程,四个线程执行顺序为 abcd,且输出为 0 1 2 1 0 1 2 1 0
* 1..... 共...
在多线程的情况下,由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。
一. java Thread类的几个函数的说明:
 1.  setPriority( ): 设置线程的优先权;
    2 . yield( ): 暂停线程的执行,给其它具有相同优先权的线程执行的...
1.对于wait()和notify()的理解对于wait()和notify()的理解,还是要从jdk官方文档中开始,在Object类方法中有:
1.父线程必须在子线程结束后结束 因为子线程是属于父线程的父线程要是结束了它的所有子线程也就随之消亡!
2..如果父线程先于子线程结束,那么子线程将在父线程结束的同时被迫结束。Thread.Join...
他的最新文章
讲师:王哲涵
讲师:韦玮
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
家境小康, 积分 1117, 距离下一级还需 883 积分
论坛徽章:0
子线程先退出的代码
#include &pthread.h&
#include &stdio.h&
void* thrd_start_routine(void* v)
{
& & sleep(5);
& & & & printf(&created thread\n&);
}
int main()
{
& & & & pthread_
& & & & & & & &
& & & & pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
& & & &
& & & & sleep(10);
& & & & printf(&main thread\n&);
& & & &
& & & & return&&0;
}
复制代码
created thread
//又过了5秒
main thread
主线程先退出
#include &pthread.h&
#include &stdio.h&
void* thrd_start_routine(void* v)
{
& & sleep(10);
& & & & printf(&created thread\n&);
}
int main()
{
& & & & pthread_
& & & & & & & &
& & & & pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
& & & &
& & & & sleep(5);
& & & & printf(&main thread\n&);
& & & &
& & & & return&&0;
}
复制代码
main thread
//退出了,切换到了shell,而且在5秒内用ps -ef | grep thread(编译生成的程序)也看不到了
是主线程退出时,子线程会强制退出吗?
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
小富即安, 积分 4153, 距离下一级还需 847 积分
论坛徽章:0
家境小康, 积分 1877, 距离下一级还需 123 积分
论坛徽章:1
当然也有方法实现主线程先退出,子线程继续
论坛徽章:0
原帖由 chenzhanyiczy 于
14:15 发表
当然也有方法实现主线程先退出,子线程继续
如何做呢?
大富大贵, 积分 16071, 距离下一级还需 3929 积分
论坛徽章:0
主线程退出,进程也就结束了,系统回收所有资源
子线程还能继续运行?
家境小康, 积分 1117, 距离下一级还需 883 积分
论坛徽章:0
又写了两个测试代码
1:主进程退出时,不管子、孙...线程都会退出
& &&&但是不是创建子线程的线程退出,被他创建的子线程都要退出,比如下面的的子线程创建了孙线程,子线程先退出,孙线程没有退出
#include &pthread.h&
#include &stdio.h&
void* fun(void* v)
{
& & sleep(10);
& & printf(&grandson thread\n&);
}
void* thrd_start_routine(void* v)
{
& & pthread_
& & pthread_create(&thd, NULL, &fun, NULL);
& & sleep(5);
& & & & printf(&created thread\n&);
}
int main()
{
& & & & pthread_
& & & & & & & &
& & & & pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
& & & &
& & & & sleep(15);
& & & & printf(&main thread\n&);
& & & & return&&0;
}
复制代码
created thread
//又过了5秒
grandson thread
//又过了5秒
main thread
------------------------------------------------------------------------------------------
2:如果主线程调用了pthread_exit,那么它退出了,子线程也不会推出
#include &pthread.h&
#include &stdio.h&
void* thrd_start_routine(void* v)
{
& & sleep(10);
& & & & printf(&created thread\n&);
}
int main()
{
& & & & pthread_
& & & & & & & &
& & & & pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
& & & &
& & & & sleep(5);
& & & & printf(&main thread\n&);
& & & & pthread_exit(NULL);
& & & & return&&0;
}
复制代码
main thread
//又过了5秒
created thread
大富大贵, 积分 16071, 距离下一级还需 3929 积分
论坛徽章:0
TO: zhongyj
我在想,你测试的结果之所以是这样,会不会是因为线程sleep阻塞住了。这样线程无法退出,只能等sleep时间到了之后再退出?
小富即安, 积分 4153, 距离下一级还需 847 积分
论坛徽章:0
同楼上一样想法。。。。
家境小康, 积分 1117, 距离下一级还需 883 积分
论坛徽章:0
回复 #7 雨过白鹭洲 的帖子
你是说的上面的
2:如果主线程调用了pthread_exit,那么它退出了,子线程也不会推出
这个代码和上面主线程先退出,子线程也退出的代码只是多了句pthread_exit(NULL);
而且sleep的时间差了5秒,不会阻塞这么长时间吧
大富大贵, 积分 16071, 距离下一级还需 3929 积分
论坛徽章:0
回复 #9 zhongyj 的帖子
子线程退出,孙线程不会退出这个很好理解
但主线程退出时调用pthread_exit,然后你仍然return 0,这时候主线程应该还是退出了,按照main的定义,进程就应该结束了
我查一下pthread_exit先。。}

我要回帖

更多关于 python 多线程 退出 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信