• [改善Java代码]不推荐覆写start方法


    多线程比较简单的方式是继承Thread类,然后覆写run()方法,在客户端程序中通过调用对象的start方法即可启动一个线程,这个是多线程程序的标准写法.

    错误代码:

     1 public class Client {
     2     public static void main(String[] args) throws InterruptedException {
     3         // 多线程对象
     4         MultiThread multiThread = new MultiThread();
     5         // 启动多线程
     6         multiThread.start();
     7 
     8     }
     9 }
    10 
    11 class MultiThread extends Thread {
    12      @Override
    13      public void start(){
    14          //调用线程体
    15          run();
    16      }
    17 
    18     @Override
    19     public void run() {
    20         // MultiThread do something.
    21         while(true){
    22             System.out.println(Thread.currentThread().getId() + "---我执行了");
    23         }
    24     }
    25 }

    这是一个错误的多线程应用,main方法根本没有启动一个子线程,整个应用程序中,只有一个主线程在运行,并不会创建任何其他的线程.

    只要删除MultiThread类中的start方法即可.

     1 public class Client {
     2     public static void main(String[] args) throws InterruptedException {
     3         // 多线程对象
     4         MultiThread multiThread = new MultiThread();
     5         // 启动多线程
     6         multiThread.start();
     7 
     8     }
     9 }
    10 
    11 class MultiThread extends Thread {
    12     // @Override
    13     // public void start(){
    14     // //调用线程体
    15     // run();
    16     // }
    17 
    18     @Override
    19     public void run() {
    20         // MultiThread do something.
    21         while(true){
    22             System.out.println(Thread.currentThread().getId() + "---我执行了");
    23         }
    24     }
    25 }

     很少有人会问,为什么不必而且不能覆写start方法,仅仅就是因为"多线程应用就是这样写的"这个原因?

    说明这个原因要看Thread类的源代码.

    public synchronized void start() {
        //判断线程状态,必须是未启动的状态
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        //加入线程组中
        group.add(this);
        //分配占内存,启动线程,运行run方法
        start0();
        //在启动前设置了停止状态
        if(stopBeforeStart){
            stop0(throwableFromStop)
        }
    }
    //本地方法
    private native void start0();

    这里的关键是本地方法start0,它实现了启动线程,申请栈内存,运行run方法,修改线程状态等职责,线程管理和栈内存管理都是由JVM负责的,如果覆盖了start方法,也就是撤销了线程管理和栈内存管理的能力,这样如何启动一个线程呢?

    事实上,不需要关注线程和栈内存的管理,只需要编码者实现多线程的业务逻辑即可(即run方法体),这也是JVM比较聪明的地方,简化多线程应用.

    那如果非要覆写start方法,如何处理?这确实是一个罕见的要求,但是覆写也很容易,只要在start的方法上加上super.start()即可.

     1 public class Client {
     2     public static void main(String[] args) {
     3         
     4     }
     5 }
     6 
     7 
     8 class MultiThread extends Thread{
     9     @Override
    10     public void start(){
    11         super.start();
    12         /*其他业务处理,但是不能调用run方法*/
    13     }
    14     
    15     @Override
    16     public void run(){
    17         //MultiThread do something.
    18     }
    19 }

    此方式虽然解决了覆写start方法的问题,但是基本上无用武之地,到目前为止还没有发现一定要覆写start方法的多线程应用.所有要求覆写start的场景,都可以通过其他的方式来实现,例如:类变量,事件机制,监听等方式.

  • 相关阅读:
    6.1(续)索引、索引组织表--Oracle模式对象
    Docker容器中用户权限管理
    setfacl、getfacl
    Premiere常见配置优化
    SSH代理
    给U盘分区
    IO模型
    window 系统各个版本 ie浏览器 默认版本 bootstrap ie版本兼容
    代码多版本处理及自动化打包部署流程
    vue3 watch 监听数组 对象
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/5623466.html
Copyright © 2020-2023  润新知