不灭的焱

革命尚未成功,同志仍须努力下载JDK17

作者:Albert.Wen  添加时间:2022-10-06 16:30:31  修改时间:2023-01-31 20:16:01  分类:Java基础  编辑

情况1:正常情况下,主线程启动了子线程,主线程、子线程各自执行,彼此不受影响。

(如评论所述,确实有问题,main线程执行完成之后,java虚拟机就退出了,那是不是可以这样猜想,main线程退出,那么Lift off thread也会退出,导致虚拟机中没有线程运行了,于是退出进程?请大神解释)

当你在run一个Java application的时候,这个时候系统会开一个进程。然后这个进程启动了Main线程。Java进程确定虚拟机中没有线程运行的时候,退出进程。或者也可以用System.exit(0);强制退出进程

代码示例如下:参考Thinkingin java代码

class LiftOff implements Runnable {
 
    Logger logger = LoggerFactory.getLogger(LiftOff.class);
 
    protected int countDown = 10; // Default
    private static int taskCount = 0;
    private final int id = taskCount++;
    public LiftOff() {}
    public LiftOff(int countDown) {
        this.countDown = countDown;
    }
    public String status() {
        return "#" + id + "(" +
                (countDown > 0 ? countDown : "Liftoff!") + "), ";
    }
    @Override
    public void run() {
        while(countDown-- > 0) {
            logger.info(status());
            Thread.yield();
        }
    }
}
 
public class MainThread{
 
    Logger logger = LoggerFactory.getLogger(MainClass.class);
 
    @Test
    public void test(){
        Thread t = new Thread(new LiftOff());
        t.start();
        t.setName("lift off thread");
        logger.info("waiting for liftoff");
    }
}

显示结果:

 

另外一个示例:

package com.wanma.apps.tool;

public class MyTest {
    /**
     * main方法
     */
    public static void main(String[] args) {
        final long timeInterval = 1000;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("Hello alibaba");
                    try {
                        Thread.sleep(timeInterval);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("aaa");
    }
}

输出:

Hello alibaba
aaa
Hello alibaba
Hello alibaba
Hello alibaba
Hello alibaba

主线程早退出了,但子线程还在执行(Java进程还没退出)。。。

情况2:需求是主线程执行结束,由主线程启动的子线程都结束

代码如下:

class SimpleDaemons implements Runnable {
    Logger logger = LoggerFactory.getLogger(SimpleDaemons.class);
    public void run() {
        try {
            while (true) {
                TimeUnit.MILLISECONDS.sleep(100);
                logger.info("run..");
            }
        } catch (InterruptedException e) {
            logger.info("sleep() interrupted");
        }
    }
}
 
public class MainThread {
    Logger logger = LoggerFactory.getLogger(MainThread.class);
    @Test
    public void test() {
        for(int i = 0; i < 5; i++) {
            Thread daemon = new Thread(new SimpleDaemons());
            daemon.setDaemon(true); // Must call before start()
            daemon.start();
        }
        logger.info("All daemons started");
        try {
            TimeUnit.MILLISECONDS.sleep(175);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

情况3:需求是子线程执行结束,主线程等待启动的子线程都结束之后再结束

代码:

public class IsAliveTest {
    public static void main(String args[]) throws Exception {
 
        Thread t = new Thread(new ThreadDemo());
        // this will call run() function
        t.start();
 
        // waits for this thread to die
        t.join();
 
        // tests if this thread is alive
        System.out.println("thread t status = " + t.isAlive());
        System.out.println("thread main status = " + Thread.currentThread().isAlive());
    }
}
 
class ThreadDemo implements Runnable {
 
    public void run() {
 
        Thread t = Thread.currentThread();
        // tests if this thread is alive
        System.out.println("status = " + t.isAlive());
        try {
            t.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试结果:

 

什么情况下一个 java thread reach the ‘Die’ state?

From the ThreadAPI, here is a complete list:

  1. If the run() method returns. 例如join()之后

  2. If an exception is thrown that propagates beyond the run method.

  3. If it is a daemon thread and all non-daemonthreads have 'died' 非后台线程都结束

  4. If the exit method of class Runtime has been called (even at another thread).

 

实际上,我们对Thread类没有什么控制权,我们几乎不能设置线程的任何状态,我们只能创建任务,并通过某种方式使用线程驱动这个任务

所以,在编写多线程代码的时候,遵循规则就变得非常重要

 

 

摘自:https://blog.csdn.net/u013905744/article/details/73741056