Loading

Java多线程-深究Runnable和Thread的区别

使用Thread实现多线程

public class MyThread extends Thread {

    private int ticket = 5;

    @Override
    public void run() {
        while (true) {
            System.out.println("Thread ticket = " + ticket--);
            if (ticket < 0) {
                break;
            }
        }
    }

}

public class Test {
    public static void main(String[] args) {

            //Test Thread

        new MyThread().start();
        new MyThread().start();

    }
}

结果

Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0
Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0

并不能实现资源共享,跟常规答案Runnable便于实现资源共享,而Thread不能一致,但真的是这样吗?仔细看一下,代码中创建了两个MyThread对象,每个对象都有自己的ticket成员变量,当然会多卖1倍。现在重新测试一下,请看测试代码:

public class Test {
    public static void main(String[] args) {

            //Test Thread

        MyThread t1 = new MyThread();
        new Thread(t1).start();
        new Thread(t1).start();
    }
}

结果

Thread ticket = 5
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 1
Thread ticket = 0
Thread ticket = -1

可以看到这次只创建了一个MyThread对象,并没出现卖两倍票的情况,Thread也可以实现资源共享。
因为多线程访问同一变量会有并发问题(需要加锁),所以Thread正确的写法如下:

public class MyThread extends Thread {

    private int ticket = 5;

    @Override
    public void run() {
        if (ticket > 0) {
            synchronized (this) {
                if (ticket > 0) {
                    while (true) {
                        System.out.println("Thread:" + Thread.currentThread().getName() + "--Thread ticket = " + ticket--);
                        if (ticket < 0) {
                            break;
                        }
                    }
                }
            }
        }
    }
}

public class Test {
    public static void main(String[] args) {
            //Test Thread
        MyThread t1 = new MyThread();
        new Thread(t1).start();
        new Thread(t1).start();
        new Thread(t1).start();
        new Thread(t1).start();
        new Thread(t1).start();
        new Thread(t1).start();
    }
}

结果

Thread:Thread-1--Thread ticket = 5
Thread:Thread-1--Thread ticket = 4
Thread:Thread-1--Thread ticket = 3
Thread:Thread-1--Thread ticket = 2
Thread:Thread-1--Thread ticket = 1
Thread:Thread-1--Thread ticket = 0

二者源码角度比较

//Thread
public class Thread implements Runnable {}

//Runnable
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

其实Thread也就是实现了Runnable接口,提供了更多的方法而已。所以说Thread与Runnable并没有什么区别。如果硬要说有什么区别的话,那就是类与接口的区别,继承与实现的区别。

参考资料:

1、转改自J-Simon

2、彻底理解Runnable和Thread的区别

posted @ 2022-02-13 00:51  Cn_FallTime  阅读(26)  评论(0编辑  收藏  举报