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

错误代码:

 public class Client {
public static void main(String[] args) throws InterruptedException {
// 多线程对象
MultiThread multiThread = new MultiThread();
// 启动多线程
multiThread.start(); }
} class MultiThread extends Thread {
@Override
public void start(){
//调用线程体
run();
} @Override
public void run() {
// MultiThread do something.
while(true){
System.out.println(Thread.currentThread().getId() + "---我执行了");
}
}
}

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

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

 public class Client {
public static void main(String[] args) throws InterruptedException {
// 多线程对象
MultiThread multiThread = new MultiThread();
// 启动多线程
multiThread.start(); }
} class MultiThread extends Thread {
// @Override
// public void start(){
// //调用线程体
// run();
// } @Override
public void run() {
// MultiThread do something.
while(true){
System.out.println(Thread.currentThread().getId() + "---我执行了");
}
}
}

很少有人会问,为什么不必而且不能覆写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()即可.

 public class Client {
public static void main(String[] args) { }
} class MultiThread extends Thread{
@Override
public void start(){
super.start();
/*其他业务处理,但是不能调用run方法*/
} @Override
public void run(){
//MultiThread do something.
}
}

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

[改善Java代码]不推荐覆写start方法的更多相关文章

  1. [改善Java代码]推荐覆写toString方法

    建议49: 推荐覆写toString方法 为什么要覆写toString方法,这个问题很简单,因为Java提供的默认toString方法不友好,打印出来看不懂,不覆写不行,看这样一段代码: public ...

  2. [改善Java代码]不推荐使用binarySearch对列表进行检索

    对一个列表进行检索时,我们使用的最多的是indexOf方法,它简单好用,而且也不会出错,虽然它只能检索到第一个符合条件的值,但是我们可以生成子列表后再检索.这样也就可以查找到所有符合条件的值了. Co ...

  3. 改善JAVA代码01:考虑静态工厂方法代替构造器

    前言 系列文章:[传送门]   每次开始新的一本书,我都会很开心.新书新心情. 正文 静态工厂方法代替构造器 说起这个,好多可以念叨的.做了一年多的项目,慢慢也有感触. 说起构造器 大家很明白,构造器 ...

  4. [改善Java代码]不要覆写静态方法

    建议33: 不要覆写静态方法 我们知道在Java中可以通过覆写(Override)来增强或减弱父类的方法和行为,但覆写是针对非静态方法(也叫做实例方法,只有生成实例才能调用的方法)的,不能针对静态方法 ...

  5. [改善Java代码]覆写equals方法必须覆写hashCode方法

    覆写equals方法必须覆写hashCode方法,这条规则基本上每个Javaer都知道,这也是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢?本建议就来解释该问题,我们先 ...

  6. [改善Java代码]覆写equals方法时不要识别不出自己

    建议45: 覆写equals方法时不要识别不出自己 我们在写一个JavaBean时,经常会覆写equals方法,其目的是根据业务规则判断两个对象是否相等,比如我们写一个Person类,然后根据姓名判断 ...

  7. [改善Java代码]覆写变长方法也循规蹈矩

    建议6:覆写变长方法也循规蹈矩 在Java中,子类覆写父类中的方法很常见,这样做既可以修正Bug也可以提供扩展的业务功能支持,同时还符合开闭原则(Open-Closed Principle),我们来看 ...

  8. [改善Java代码]asList方法产生的List对象不可更改

    上一个建议之处了asList方法在转换基本类型数组时候存在的问题,在看下asList方法返回的列表有何特殊的地方.看代码: import java.util.Arrays; import java.u ...

  9. [改善Java代码]避免对象的浅拷贝

    建议43: 避免对象的浅拷贝 我们知道一个类实现了Cloneable接口就表示它具备了被拷贝的能力,如果再覆写clone()方法就会完全具备拷贝能力.拷贝是在内存中进行的,所以在性能方面比直接通过ne ...

随机推荐

  1. Caroline--chochukmo

    Caroline--chochukmo 虾米试听 Caroline, Caroline, Caroline, you pulled me into so deep down(内心深处). Caroli ...

  2. jquery easyui的扩展验证

    1.扩展通过$.extends($.fn.validatebox.defaults.rules,)扩展 $.extend( $.fn.validatebox.defaults.rules, { idc ...

  3. thymeleaf中的th:remove用法

    一.删除模板片段使用th:remove属性 th:remove的值如下: 1.all:删除包含标签和所有的孩子. 2.body:不包含标记删除,但删除其所有的孩子. 3.tag:包含标记的删除,但不删 ...

  4. mongoDB在windows下基于配置文件的安装和权限配置方式

    下载mongoDB  http://www.mongodb.org/downloads 根据操作系统,选择需要下载的安装包 添加mongodb 安装目录 将解压的文件夹中内容拷贝,存放在想要安装的文件 ...

  5. oracle的substr和replace

    //我个人做的是更新表中某个字段下的所有内容带有中文括号的信息变为英文括号,具体做法如下 update 表名 set 列名 =replace(要修改的字段名,要替换掉的内容,要替换上去的新内容) su ...

  6. CodeForces 707A Brain's Photos (水题)

    题意:给一张照片的像素,让你来确定是黑白的还是彩色的. 析:很简单么,如果有一种颜色不是黑白灰,那么就一定是彩色的. 代码如下: #pragma comment(linker, "/STAC ...

  7. JMS开发(一):基础理论认知

    JMS全称是Java Message Service.其是JavaEE技术规范中的一个重要组成部分,是一种企业消息处理的规范.它的作用就像一个智能交换机,它负责路由分布式应用中各个组件所发出的消息. ...

  8. Protobuf一键生成代码bat文件

    最近在摆弄Unity的Socket,需要用到Protobuf,一般都会有多个协议文件,所以研究了下bat的批处理,下面给出批处理文件代码: @echo off ::协议文件路径, 最后不要跟“\”符号 ...

  9. 小学生玩ACM----广搜

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

  10. C#不错的扩展工具类

    FSLibExtension.NET https://github.com/iccfish/FSLib.Extension WebEssentials2013 https://github.com/i ...