多线程比较简单的方式是继承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. Linux服务器集群系统(一)(转)

    add by zhj:虽然是2002年的文章,但读来还是收益良多.在 章文嵩:谈LVS及阿里开源背后的精彩故事 中LVS发起人及主要贡献者谈了LVS的开发过程及阿里开源的一些故事 原文:http:// ...

  2. 【转】有向图强连通分量的Tarjan算法

    原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...

  3. Jvm基础(2)-Java内存模型

    Jvm基础(2)-Java内存模型 主内存和工作内存 Java内存模型包括主内存和工作内存两个部分:主内存用来存储线程之间的共享变量:而工作内存中存储每个线程的相关变量. 如下图所示: 需要注意的是: ...

  4. STL学习系列三:Deque容器

    1.Deque简介 deque是“double-ended queue”的缩写,和vector一样都是STL的容器,deque是双端数组,而vector是单端的. deque在接口上和vector非常 ...

  5. poj 2349 Arctic Network

    http://poj.org/problem?id=2349 Arctic Network Time Limit: 2000MS   Memory Limit: 65536K Total Submis ...

  6. mysql删除重复记录语句,删除除了 id 号不同,其他都相同的学生冗余信息

    /** 在Mysql下执行: delete from my.stu where id not in( select min(id) id from my.stu group by code) ; 用途 ...

  7. ASP导出Word带页眉页脚,中文不乱码

    关键代码: <% Response.Clear() Response.CodePage= Response.Charset="UTF-8" Response.ContentT ...

  8. extjs grid renderer用法【转载】

    今天在做项目时,需要在列表中的某列添加一个超链接,首先要取得当前选中行的数据,判断数据类型,然后链接到不同的页面,研究下.发现ExtJs提供了一个很强的方法如下: var cm = new Ext.g ...

  9. WCF 新手教程二

    基本知识: [ServiceContract] Attribute 能够有以下Property 的: CallbackContract 设置callback的类型:Duplicate指Service ...

  10. 实现一个跨平台的mysock库(windows、linux)

     源码下载 1.首先确定自己的操作系统为32位还是64位: root@bfq:~/mysock# uname -a Linux bfq 3.11.0-26-generic#45~precise1- ...