美文网首页
Runable和Thread类实现线程的异同

Runable和Thread类实现线程的异同

作者: 竹鼠不要中暑 | 来源:发表于2019-03-10 00:22 被阅读7次

    Java中通过实现Runable接口,或者继承Thread类都可以实现线程。那么他们之间有什么区别和联系呢?

    联系

    • Thread类实现了Runable接口。
    • 都需要重写run方法。

    区别

    • 实现Runnable接口的方法使程序更具有健壮性,可以避免单继承的局限;
    • Runnable更容易实现资源共享,能多个线程同时处理一个资源,代码与数据是独立的。

    例子

    下面以买票为例,假设火车站共有三个售票窗口,每个窗口买一张票费时1秒钟,共有5张票。

    • 继承Thread实现:
    public class MyThread1 extends Thread {
        private int tickets = 5;
    
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            int number = 0;
            while (true) {
                if (tickets <= 0) {
                    System.out.println("票已售罄");
                    break;
                }
                System.out.println(name + " 售出 " + ++number + " 张票,剩余票数:" + --tickets);
    
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    public class ThreadDemo {
        public static void main(String[] args) {
            new MyThread1().start();
            new MyThread1().start();
            new MyThread1().start();
        }
    }
    

    运行结果:

    Thread-1 售出 1 张票,剩余票数:4
    Thread-0 售出 1 张票,剩余票数:4
    Thread-2 售出 1 张票,剩余票数:4
    Thread-1 售出 2 张票,剩余票数:3
    Thread-0 售出 2 张票,剩余票数:3
    Thread-2 售出 2 张票,剩余票数:3
    Thread-1 售出 3 张票,剩余票数:2
    Thread-0 售出 3 张票,剩余票数:2
    Thread-2 售出 3 张票,剩余票数:2
    Thread-1 售出 4 张票,剩余票数:1
    Thread-0 售出 4 张票,剩余票数:1
    Thread-2 售出 4 张票,剩余票数:1
    Thread-1 售出 5 张票,剩余票数:0
    Thread-0 售出 5 张票,剩余票数:0
    Thread-2 售出 5 张票,剩余票数:0
    票已售罄
    票已售罄
    票已售罄
    

    可以看到,三个窗口均售出了5张票。

    • Runnable实现
    public class MyThread2 implements Runnable {
        private int tickets = 5;
        Object lock = new Object();
    
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            int number = 0;
            while (true) {
                if (tickets <= 0) {
                    System.out.println("票已售罄");
                    break;
                }
                System.out.println(name + " 售出 " + ++number + " 张票,剩余票数:" + --tickets);
    
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    
    public class RunnableDemo {
        public static void main(String[] args) {
            MyThread2 myThread = new MyThread2();
            new Thread(myThread).start();
            new Thread(myThread).start();
            new Thread(myThread).start();
        }
    }
    

    运行结果:

    Thread-0 售出 1 张票,剩余票数:4
    Thread-1 售出 1 张票,剩余票数:3
    Thread-2 售出 1 张票,剩余票数:2
    Thread-0 售出 2 张票,剩余票数:1
    Thread-1 售出 2 张票,剩余票数:0
    票已售罄
    票已售罄
    票已售罄
    

    可以看到,三个窗口共同售出了5张票,且0号和1号窗口均售出2张,2号窗口售出1张。

    注意:多线程共享资源时,如上例中3个Thread对象共同执行一个Runnable对象中的代码,可能会造成线程的不安全,比如leftTickets可能会为-1。这就需要加入同步操作(即互斥锁,synchronized或自定义),确保同一时刻只有一个线程在执行每次循环中的操作。

    相关文章

      网友评论

          本文标题:Runable和Thread类实现线程的异同

          本文链接:https://www.haomeiwen.com/subject/afuypqtx.html