多线程Demo学习(创建线程,查看线程的运行状态,查看线程名)

本文介绍Java中线程的创建及状态转换方法,并演示如何获取JVM中线程名称。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.第一个多线程程序

public class Text {
    public static void main(String[] args) {
        DoThread();
    }

    protected static void DoThread(){
        final StringBuilder sb=new StringBuilder();
        for(int i=0;i<10;i++){
            new Thread(){
                public void run(){
                    System.out.println("Java并发");
                }
            }.start();
        }

        for(int i=0;i<10;i++){
            new Thread(){
                @Override
                public void run() {
                    System.out.println("Java编程");
                }
            }.start();
        }
    }
}

上面代码通过最简单的方式来创建线程并开始:

            new Thread(){
                public void run(){
                    System.out.println("Java并发");
                }
            }.start();

类似大家可以通过其他的方式来代替上面的部分(Runnable方式等)

下面是运行结果:
在这里插入图片描述

2.查看线程的运行状态

public class Text {
    public static void main(String[] args) throws InterruptedException{
       ThreadState state = new ThreadState();//新建任务对象
       Thread thread = new Thread(state);//新建一个线程
        System.out.println("新建线程:"+thread.getState());
        thread.start();//让线程开始
        System.out.println("启动线程:"+thread.getState());
        Thread.sleep(100);//使线程睡眠0.1s
        System.out.println("计时等待"+thread.getState());
        Thread.sleep(1000);//使线程睡眠1s
        System.out.println("等待线程"+thread.getState());
        state.notifyNow();//唤醒该线程
        System.out.println("唤醒线程"+thread.getState());
        Thread.sleep(1000);//又使线程睡眠1s
        System.out.println("线程终止:"+thread.getState());

    }
}

class ThreadState implements Runnable{//自定义任务

    //使执行此任务的线程等待0.5秒
    public synchronized void waitForASecond() throws InterruptedException{
        wait(500);
    }
    //使执行此任务的线程无限等待
    public synchronized void waitForYears() throws InterruptedException{
        wait();
    }
    //唤醒执行此任务的线程
    public synchronized void notifyNow() throws InterruptedException{
        notify();
    }

    @Override
    public void run() {
        try{
            waitForASecond();//让线程等待0.5秒
            waitForYears();//让线程等待
             for (int i=0;i<10000;i++){

            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

下面我们解析上面代码的主方法运行过程:
首先主线程开始,给主方法分配栈帧
然后新建任务对象和子线程对象放到堆中,此时子线程thread处于新建状态NEW
所以第一个输出语句 打印的是: 新建线程: NEW
然后调用start()方法让线程thread启动,启动后的线程的状态为RUNNABLE,所以后面打印的是: 启动线程:RUNNABLE
注意后面调用的是sleep()让main线程处于睡眠状态0.5s,之后,子线程运行waitForASecoond()处于计时等待状态,所以后面打印的是: 计时等待:TIMED_WAITING
之后又让mian线程睡眠1s,此时子线程的计时等待以及结束,进入下面的无限等待状态,所以下面的打印信息为:
等待线程WAITING
然后,主线程调用任务对象的notifyNow()方法来唤醒子线程,所以下面打印:唤醒线程:RUNNABLE
之后主线程等待1秒,子线程结束,此时打印:线程终止:TERMINATED

运行结果:
在这里插入图片描述

3.查看JVM中的线程名

要实现这个功能我们需要用到ThreadGroup这个API, ThreadGroup表示一个线程的集合,此外,线程组也可以包含其他线程组,所以线程组可以构成一棵树,在树中,除了初始线程组外,每个线程都有一个父线程组。 我们允许线程访问有关自己的线程组的信息,但不允许它访问有关其他线程组的父线程组或者其他线程组的信息。
这个类的常用方法有:

方法名作用
activeCount()返回此线程组中的活动线程的估计数
activeGroupCount()返回此线程组中活动线程组的估计数
enumerate(Thread[] list,boolean recurse)把此线程组中的所有活动线程复制到指定数组中
enumerate(ThreadGroup[] list,boolean recurse)把对此线程组中的所有活动子组的引用复制到指定数组中
getName()返回此线程组的名称
getParent()返回此线程组的父线程组
public class Text {

    public static void main(String[] args) throws InterruptedException{
        for (String string:getThreadGroups(getRootThreadGroup())){
            System.out.println(string);
        }
    }
    //获得根线程组
    private static ThreadGroup getRootThreadGroup(){
        ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
        while(true){
            if(rootGroup.getParent()!=null){
                rootGroup = rootGroup.getParent();
            }else{
                break;
            }
        }
        return rootGroup;
    }
    //获取活跃线程列表
    public static List<String> getThreads(ThreadGroup group){
        List<String> threadList = new ArrayList<String>();//新建一个列表
        Thread[] threads = new Thread[group.activeCount()];//建立活跃线程数组
        int count = group.enumerate(threads,false);//将活跃的线程复制到threads数组中
        for(int i=0;i<count;i++){
            threadList.add(group.getName()+"线程组:"+threads[i].getName());//将线程名逐个添加到线程列表中
        }
        return threadList;//返回线程列表
    }

    //获取线活跃程组列表
    public static List<String> getThreadGroups(ThreadGroup group){
        List<String> threadList = getThreads(group);
        ThreadGroup[] groups = new ThreadGroup[group.activeGroupCount()];
        int count = group.enumerate(groups,false);
        for(int i=0;i<count;i++){
            threadList.addAll(getThreads(groups[i]));
        }
        return threadList;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值