2.线程实现

文章介绍了在Java中实现线程的两种主要方式——实现Runnable接口和继承Thread类,并详细解释了两种方式的区别,包括避免单继承限制、解耦run方法、以及数据共享能力。官方推荐使用Runnable接口来创建线程。同时,文章提供了一个示例,展示了当同时使用两种方式时,执行的是Thread类的run方法。
摘要由CSDN通过智能技术生成

1.实现线程的方式
Oracle官方文档阐述了两种实现线程的方式,一种是实现Runnable接口并重写run方法,另一种是继承Thread类并重写run方法,两种实现方式的代码分别如下所示。

/**
 * 描述:使用Runnable接口的方式实现线程。
 */
public class RunnableStyle implements Runnable {
    @Override
    public void run() {
        System.out.println("使用Runnable接口的方式实现线程");
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new RunnableStyle());
        thread.start();
    }
}
/**
 * 描述:使用继承Thread类的方式实现线程。
 */
public class ThreadStyle extends Thread{
    @Override
    public void run() {
        System.out.println("使用继承Thread类的方式实现线程");
    }

    public static void main(String[] args) {
        ThreadStyle thread = new ThreadStyle();
        thread.start();
    }
}

2.两种实现方式的区别
官方建议使用Runnable方式实现线程,原因主要有以下三点。

  • Runnable可避免Java单继承的缺陷。如果一个类本身已经继承一个父类,那么该类将无法通过继承Thread类的方式实现线程。
  • Runnable可避免子类继承Thread类中除run和start以外的方法。实现线程任务的run方法,应该要将其从该类中解耦出来。
  • Runnable可以有共享数据。使用同一个Runnable构造的不同线程之间是可以共享数据的,而Thread类不能共享数据。

3.实现细节
从上述两种实现方式的代码来看,本质上,都是通过Thread类的构造方法来创建线程的,只是一个传递了Runnable实例,一个没有。如果继承Thread类,那么run方法会被完全覆盖,执行子类的run方法,里面的判断逻辑将不会执行。而实现Runnable接口时,传入Runnable实例,run方法里的判断逻辑将会被执行,调用的是实例的run方法。具体源代码如下所示。

public interface Runnable {
	public abstract void run();
}
public class Thread implements Runnable {
	private Runnable target;
	
	private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
	    init(g, target, name, stackSize, null, true);
	}
	
	public Thread() {
	    init(null, null, "Thread-" + nextThreadNum(), 0);
	}
	
	public Thread(Runnable target) {
	    init(null, target, "Thread-" + nextThreadNum(), 0);
	}
	
	@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
}

4.思考题
分析以下代码执行结果并思考原因。

/**
 * 描述:同时使用Runnable和Thread两种实现线程的方式。
 */
public class BothRunnableAndThread {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("使用Runnable接口的方式实现线程");
            }
        }){
            @Override
            public void run() {
                System.out.println("使用继承Thread类的方式实现线程");
            }
        }.start();
    }
}

代码运行结果如下所示,由此可知,当同时使用两种线程实现方式时,执行的是Thread类的run方法,原因是当Thread类的run方法被覆盖时, target.run()便不会被执行,即Runnable的run方法不会被执行。

使用继承Thread类的方式实现线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值