博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[改善Java代码]不推荐覆写start方法
阅读量:5775 次
发布时间:2019-06-18

本文共 2484 字,大约阅读时间需要 8 分钟。

多线程比较简单的方式是继承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      @Override13      public void start(){14          //调用线程体15          run();16      }17 18     @Override19     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     // @Override13     // public void start(){14     // //调用线程体15     // run();16     // }17 18     @Override19     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     @Override10     public void start(){11         super.start();12         /*其他业务处理,但是不能调用run方法*/13     }14     15     @Override16     public void run(){17         //MultiThread do something.18     }19 }

 

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

 

转载于:https://www.cnblogs.com/DreamDrive/p/5623466.html

你可能感兴趣的文章
js/jQuery中单选框、下拉框的取值、设置
查看>>
本地也能运行AWS?是的,AWS开始进军混合云领域了
查看>>
十年中文技术社区风雨之路 今晚4位老炮畅聊过去未来
查看>>
数人云Mesos调度器Swan v0.2最新功能演示
查看>>
Java String、StringBuffer和StringBuilder类
查看>>
通过DevOps考古学了解生产环境
查看>>
使用C#进行系统编程
查看>>
天天都在说,无服务器计算到底是什么?
查看>>
实时监控系统如何帮助FreeWheel支持超级赛事直播广告?
查看>>
Fake 5提供.NET Core支持
查看>>
贝壳金控赵文乐:基于 Spring Cloud 的服务治理实践
查看>>
Java程序员:不要因未知而让云成本大涨
查看>>
PHP|标准配置之php.ini (2)
查看>>
python冒泡排序
查看>>
Springboot+Mybatis+Shiro实现角色权限管理
查看>>
DataWorks是如何做到协同开发和版本控制
查看>>
程序员请放下浮躁的心
查看>>
CS0234 The type or namespace name 'Mvc' does not exist in the namespace 'Microsoft.AspNet' (are you
查看>>
实战 Docker+Kubernetes 微服务容器化(一)-初识微服务
查看>>
Java集合类: Set、List、Map、Queue使用场景梳理
查看>>