20Java线程状态(二)

线程状态

join插队(加入):写在哪个线程体中,这个线程就被阻塞

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Bxq4Hn1-1630079479534)(E:(A)]PostgraduateFlies\JavaLearning\TyporaFiles\第二阶段\30Java的线程状态二.assets\image-20210720230001553.png)

与sleep方法的区别是:

  • join是成员方法,必须使用线程的对象来调用join方法;
  • sleep是Thread类方法,直接Thread.sleep().
join状态的程序
package ThreadStudy;

/**测试join线程状态,插队
 *
 *
 * @author 发达的范
 * @version 1.0
 * @date 2021/07/22 21:28
 */
public class BlockJoin {
    public static void main(String[] args) throws InterruptedException {
//        //使用lambda表达式开启一个线程
//        new Thread(()-> {
//                for (int i = 0; i < 10; i++) {
//                    System.out.println(i);
//                }
//        }).start();

//        //或者可以使用匿名内部类写成
          //匿名内部类需要借助父类或者接口
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                for (int i = 0; i < 10; i++) {
//                    System.out.println(i);
//                }
//            }
//            }).start();

        //因为join是线程对象的方法,对象需要多次使用,所以不使用匿名,使用lambda表达式
        Thread t = new Thread(()->{
            for (int i = 0; i < 100; i++) {
                    System.out.println("t "+i);
                }
        });
        t.start();

        for (int i = 0; i < 100; i++) {
            if (i % 20 == 0) {
                t.join();
            }
            System.out.println("main "+i);
        }
    }
}

运行结果:不截图了,经过多次实验发现每次都是t线程运行完成后再运行主线程,这只是CPU的调度原因,并不影响我们分析程序。理论上来说,运行结果应该是t线程和main线程同时运行,当main线程运行到i==20时候,t线程join(插队),然后就只运行t线程,等到t线程运行结束后再运行main线程。

注意:join线程和sleep线程一样,都需要处理异常。

下面是测试join()的程序:
package ThreadStudy;

/**爸爸和儿子买烟的故事
 *
 * @author 发达的范
 * @version 1.0
 * @date 2021/07/22 21:28
 */
public class BlockJoin02 {
    public static void main(String[] args)  {
        System.out.println("爸爸和儿子买烟的故事");
        new Thread(new Dad()).start();//只需要使用一次的类,所以使用匿名
    }
}

class Dad extends Thread {
    @Override
    public void run() {
        System.out.println("爸爸想抽烟,发现烟没了");
        System.out.println("给儿子钱,让儿子去买烟");
        Thread t = new Thread(new Son());
        t.start();//此时开启儿子线程,让儿子去买烟
//        try {
//            t.join();//重点
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        System.out.println("爸爸接过烟,把零钱给了儿子");
    }
}

class Son extends Thread {
    @Override
    public void run() {
        System.out.println("接过爸爸的钱出门了");
        System.out.println("路边有个游戏机,去玩了一会");
            try {
                System.out.println("一小时过去了");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        System.out.println("赶紧买烟去");
        System.out.println("买完烟回家了");
    }
}

运行结果:

可以看到,没有使用join进行插队,父亲线程和儿子线程开启后同时运行,导致做事的顺序乱了。在父类线程中加入join之后,运行到,运行到儿子对象的线程的时候父亲线程会阻塞,等待儿子线程运行完成之后再执行父亲线程后面的语句。

线程状态

测试线程状态
package ThreadStudy;
import java.lang.Thread.State;
/**
 * @author 发达的范
 * @version 1.0
 * @date 2021/07/26 20:47
 */
public class ThreadState {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("...");
        });
        State state = t.getState();
        System.out.println(state);

        t.start();//具备线程能力或者运行中统一称为RUNNABLE,因为不受人为控制,不好区分
        state = t.getState();
        System.out.println(state);

        while (state!=Thread.State.TERMINATED) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            state = t.getState();//此时是sleep的线程阻塞状态
            System.out.println(state);
        }
    }
}

运行结果:

可以看到,for循环结束之后,用户开启的线程就终止了,状态是TERMINATED,而TIMED_WAITING状态是while循环里面的每200ms捕捉一次线程状态的程序刚好在for循环执行sleep(100)的时候捕获了这个状态TIMED_WAITING。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值