java中的Thread类解析

实现线程的三种方式

1、继承Thread类,重写里面的run方法

public class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("threadName:"+Thread.currentThread().getName());
        }
    }

    /**
     * 方式一:继承Thread类,重写里面的run方法
     */
    @Test
    void thread1(){
        new MyThread().start();
    }

2、实现 Runnable 接口 这里直接用匿名内部类 实现了

@Test
    void thread2(){
        new Thread(()->{
            System.out.println("threadName:"+Thread.currentThread().getName());
        },"thread1").start();
    }

3、实现 Callable接口 然后 放到Thread 中 这样能拿到一个结果

/**
     * 方式三:实现 Callable接口 然后 放到Thread 中 这样能拿到一个结果
     * @throws ExecutionException
     * @throws InterruptedException
     * @throws TimeoutException
     */
    @Test
    void thread3() throws ExecutionException, InterruptedException, TimeoutException {
        //Callable
        final FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(TimeUnit.SECONDS.toMillis(2));
            System.out.println("ThreadName:" + Thread.currentThread().getName());
            return "success";
        });
        new Thread(futureTask).start();
        // 调用get 会阻塞在这里 ,成功拿到结果才行
        final String result = futureTask.get();
        System.out.println(result);
        System.out.println("end");
    }

:另外还可以通过线程池创建线程

main方法中线程执行分析

main方法 中 流程:进程-开启一个主线程-主线程又开启一个子线程
:主线程执行完后 子线程会继续执行。但是用@Test 注解 实现就不行。
原因:@Test 注解时,JUnit会自动创建一个测试线程来运行测试方法,并在测试方法执行完毕后立即终止该线程,而不管该线程是否已经执行完毕。因此,在使用@Test注解时,子线程可能无法执行完毕,因为测试线程已经被终止了
流程:进程-开启一个主线程-主线程又开启一个子线程


public static void main(String[] args) {
        new Thread(()->{
            for (int i = 0; i <50; i++) {
                try {
                    Thread.sleep(TimeUnit.SECONDS.toMillis(1));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:"+Thread.currentThread().getName()+",正在干活"+",count:"+(i+1));
            }
        }).start();

        for (int i = 0; i < 40; i++) {
            try {
                Thread.sleep(TimeUnit.SECONDS.toMillis(1));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程:"+Thread.currentThread().getName()+",正在干活"+",count:"+(i+1));
        }
    }

Thread方法

start()

这个就是启动线程的方法,他和run方法的区别是,start是通过本地方法private native void start0();(底层JVM调用,c/c++实现的)开启新的线程然后执行run方法。
而run方法本身就是一个普通方法。

run()

本身就是一个普通方法,如果直接调用它。比如拿刚才的例子,下面换成run方法,其实就是main线程在执行。执行完run方法里然后执行下面的,这就不是多线程了。而是一个线程在顺序执行!!!

@Test
    void mainThreadAndSonThread(){
        new Thread(()->{
            for (int i = 0; i <50; i++) {
                try {
                    Thread.sleep(TimeUnit.SECONDS.toMillis(1));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:"+Thread.currentThread().getName()+",正在干活"+",count:"+(i+1));
            }
        }).run();

        for (int i = 0; i < 40; i++) {
            try {
                Thread.sleep(TimeUnit.SECONDS.toMillis(1));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程:"+Thread.currentThread().getName()+",正在干活"+",count:"+(i+1));
        }
    }

守护线程

1、用户线程
即工作线程,线程执行完即结束了
2、守护线程
一般是为了工作线程服务的,当所有用户线程结束时,守护线程自动结束
3、常见的守护线程:垃圾回收机制
下面例子:自己开启一个守护线程,然后一直监听工作线程,等工作线程工作完成后,守护线程自己也就结束了。

@Test
    void testDaemon(){
        final Thread thread = new Thread(() -> {
            while (true){
                try {
                    Thread.sleep(TimeUnit.SECONDS.toMillis(1));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("ThreadName:"+Thread.currentThread().getName()+" 正在监听工作线程:");
            }
        },"son Thread");
        //将 son Thread 线程 设置为守护线程 当main线程结束 sonThread 线程就结束
        thread.setDaemon(true);
        thread.start();

        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(TimeUnit.SECONDS.toMillis(1));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程:"+Thread.currentThread().getName()+",正在干活"+",count:"+(i+1));
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值