01_传统线程回顾

我们知道传统创建线程的方式有两种:

一、继承Thread类,覆盖run()方法

// 继承Thread
class MyThread extends Thread{
	@Override
	public void run(){
		// do something
	}
}
// 开启线程
MyThread t1 = new MyThread();
t1.start();

二、实现Runnable接口,覆盖run()方法,使用该Runnalbe对象构造Thread类

// 实现Runnable接口
Class MyRunnable implements Runnable{
	@Override
	public void run(){
		// do something
	}
}
// 开启线程
Thread t2 = new Thread(new MyRunnable);
t2.start();

创建线程的方式很简单,不过多讨论,这里提两个问题:

问题1:能否run()方法中抛出InterruptedException异常,以便在run()方法中调用Thread.sleep()的时候,不用try...catch..

问题2:如果同时覆盖的Thread类的run()方法,也为该Thread传递了Runnable对象,那么程序运行Thread类的run()方法代码,还是执行Runnable对象的run()方法的代码呢?

解答:

问题1,明显不可以,代码写完连编译都不过,我们翻看Thread类的run()方法源码可知,

Thread类的run()方法并没有抛出异常,子类继承父类的run()方法

也就不能抛出异常,这是继承方面的知识,这里暂时不深入讨论。

源码:

class MyThread extends Thread{
	@Override
	public void run() throws InterruptedException {
		Thread.sleep(1000L);
	}
}

 编译器提示:

问题2:我们知道不管使用那种方式创建线程,最终都会调用Thread类的run()方法,

翻看Thread类的源码可知,在Thread类的run方法中有以下这段代码:

if (target != null) {

            target.run();

    }

而这个targe就是我们在构造方法传入的Runnalbe类,到这里我们应该明白,

这里分两种情况:

1)情况1:如果覆盖了Thread类的run方法,并且没有在run方法中调用super.run()方法,

则程序只会执行Thread类中的run方法代码

2)情况2:如果覆盖了Thread类的run方法,并且在run方法中第一行中调用super.run()方法,

则程序先执行Runnable类中的run方法代码,之后再执行Thread类中的run方法代码。

源码:

package com.sam;

/**
 * 传统线程回顾
 * @author SAM
 *
 */
public class TraditionalThread {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new Thread(new Runnable() {
			
			// Runnable的fun方法
			@Override
			public void run() {
				System.out.println("这是Runnable类的run方法 TName=" + Thread.currentThread().getName());				
			}
		}){
			// Thread类的run方法
			@Override
			public void run() {
				//super.run();
				System.out.println("这是Thread类的run方法 TName=" + Thread.currentThread().getName());
			};
		}.start();
	}
}

 程序执行结果:


猜你喜欢

转载自wengyoulong.iteye.com/blog/2374190