【Java多线程】Thread和Runnable创建新线程区别

这是一道面试题,创建多线程时,使用继承Thread类和实现Runnable接口有哪些区别呢?

一、Thread

先来看看Thread类和其中的start()方法

class Thread implements Runnable{.....}  
// 可见,Thread类实现了Runnable接口
public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

其中,start0()是一个native方法,在操作系统层面开启一个新线程。继承Thread类后,重写run()方法,则调用start()方法会执行子类的run()方法。

class MyThread extends Thread{
	private int count = 10;
    @Override
    public void run() {
          while(count > 0)
          	System.out.println(count--);
    }
}

public class Main{

    public static void main(String[] args) {
    	// Thread类中有start()方法,调用父类start()执行子类run()
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
}

二、Runnable

相同代码改成实现Runnable接口

class MyThread implements Runnable{
    private int count = 10;
    @Override
    public void run() {
        while(count > 0)
            System.out.println(count--);
    }
}

public class Solution {

    public static void main(String[] args) {
        Runnable myThread = new MyThread();
        new Thread(myThread).start();
        new Thread(myThread).start();
        new Thread(myThread).start();
    }
}

显然,实现Runnable接口时,3个线程共享了count变量,而在继承Thread类时,每个线程各有一个count,没有共享。在秒杀、抢票等场景中,显然实现Runnable接口符合业务逻辑。
另外,线程池中只能接受Runnable或Callable的线程。

三、总结

1、实例化线程对象的方式:

继承Thread:

new MyThread().start();

实现Runnable

Runnable myThread = new MyThread();
new Thread(myThread).start();

2、继承与接口的区别

Java中只能单继承,但接口可以实现多个,Runnable实现方式更加灵活。

3、方便共享资源

Runnable方式实现的线程方便资源共享,多个线程共同操作同一变量,符合大多数业务逻辑。

4、线程池相关

线程池只接受Runnable、Callable类线程,不能直接放入继承Thread的类。

原创文章 10 获赞 10 访问量 4752

猜你喜欢

转载自blog.csdn.net/Steven_L_/article/details/105835012