Java随笔-线程start与run

概述

开启一个线程,正确做法是调用线程start方法,但遇见过有调用run方法开启线程的,调用run方法肯定是错误的,虽然也执行了该执行的操作。

进程与线程

在这里插入图片描述
以上图中cpu为例。

  • 物理内核为6核,逻辑内核为12核,也就是1个内核中包含2个逻辑处理器,可以同时执行两个线程,12个也就是可以同时执行12个线程,并行12个线程。
  • 并行和并发是两个概念。并行是线程彼此之间互不干扰,可以一直运行下去;并发是多个线程只有一个处理器处理,离不开时间。并行就像是多条车道,多辆车可以同时通行,互不干扰;而并发就像是多条车道只有一个出口,每分钟的只能通行20辆。
  • 并行12个线程,但实际中线程有成千上万个,是因为cpu是通过时间切片的方式分配给线程,具体分配多少时间由系统和cpu决定,线程本身无法决定。一般时间很短,可以精确到纳秒,用户来不及反应。
  • 进程是用于分配资源的,进程的创建意味着需要分配一定的cup,内存,寄存器等相关资源给需要做事的线程,只管分配资源但不做事。
  • 线程是真正做事的,相关的操作和处理都是在线程中完成。
  • 一个进程中可以有多个线程,但拥有的线程数量是有上限的,具体数量多少因操作系统不同而不同。因为电脑资源是有限的,每当执行创建一个线程,都意味着要消耗一定的资源,分配太多线程资源不够分配,也会对其它任务有影响。
  • 线程依托于进程而存在,没有进程就谈不上线程。

开启线程

  • start。创建线程实例,并调用start()开启线程。
public class ThreadTest1 {

    public static void main(String[] args) {
        // 输出当前线程名称
        System.out.println(Thread.currentThread().getName());
        // 创建新线程
        ThreadPattern threadPattern = new ThreadPattern();
        // 开启新线程
        threadPattern.start();
    }

    /**
     * Thread扩展类
     */
    private static class ThreadPattern extends Thread{
        @Override
        public void run() {
            super.run();
            // 输出当前线程名称
            System.out.println(Thread.currentThread().getName());
            System.out.println("我是新新线程");
        }
    }
}

运行结果:

main
Thread-0
我是新新线程

首先在main()输出当前线程为main,也就是主线程;然后创建了新线程Thread-0,并输出当前线程名称和需要输出的语句"我是新新线程"。结果也证明确实创建了新线程,也做了该做的事。

 // 创建线程实例
ThreadPattern threadPattern = new ThreadPattern();

该代码只是创建了线程对象,什么也没有做,还没有真正成为线程。当调用start()时才开始成为真正的线程。
在这里插入图片描述
当调用start()时,start()再调用start0(),此时才算是成为真正的线程,做线程该做的事情。start0()是native方法,也就是执行start0(),才能真正调用电脑中分配的资源,利用cpu和内存做事,之前的所有准备都是逻辑处理,未真正涉及进程分配的资源。
通过观察还发现:

    /*
     * Java thread status for tools, default indicates thread 'not yet started'
     */
    private volatile int threadStatus;
    
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
          public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
         ...

threadStatus是表示线程的开启状态,等于0时表示线程未开启,不等于0时表示线程已开启,当线程开启时,再调用start()会抛出IllegalThreadStateException异常。
验证:

        // 开启新线程
        threadPattern.start();
        threadPattern.start();

结果:

main
Thread-0
我是新新线程
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.base/java.lang.Thread.start(Thread.java:791)
	at thread.ThreadTest1.main(ThreadTest1.java:17)

不出意外,第二次调用start()直接抛出了IllegalThreadStateException。所以线程start()只能调用一次。

  • run。调用创建的线程实例的run。
public class ThreadTest1 {

    public static void main(String[] args) {
        // 输出当前线程名称
        System.out.println(Thread.currentThread().getName());
        // 创建新线程
        ThreadPattern threadPattern = new ThreadPattern();
        //
        threadPattern.run();
    }
    /**
     * Thread扩展类
     */
    private static class ThreadPattern extends Thread{

        @Override
        public void run() {
            super.run();
            System.out.println(Thread.currentThread().getName());
            System.out.println("我是新新线程");
        }
    }
}

结果:

main
main
我是新新线程

结果发现虽然执行了需要执行的操作,但是并没有创建新的线程,还是在主线程main中执行的相关操作。此时创建的threadPattern只是一个简单的对象,和线程没有关系,而threadPattern.run()仅仅是调用了该对象中一个普通不能再普通的方法,仅此而已,和线程无关。

总结

  • start()是开启创建的新线程,而run()只是调用了方法而已。
  • start()只能调用一次。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值