多线程比较简单的方式是继承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的场景,都可以通过其他的方式来实现,例如:类变量,事件机制,监听等方式.