java多线程实现

java中有两种多线程的实现方式,一种是继承Thread类,一种是实现Runnable接口。

那么继承Thread类与实现Runnable接口这两种方式有什么区别呢?具体通过实际的案例来体现。

现在模拟火车售票系统,实现通过四个销售站点销售某日某车次火车100张票,一个站点用一个线程表示。

首先使用继承Thread类实现: 

public class ThreadTest extends Thread{
    
    private int ticket = 100;    
    public void run(){
        while(true){
            if(ticket > 0){
                System.out.println(Thread.currentThread().getName() + "is saling ticket" + ticket--);
            }else{
                break;
            }
        }
    }
}

其对应测试类:

public class TestDemo {

    public static void main(String[] args) {

        ThreadTest t1 = new ThreadTest();
        ThreadTest t2 = new ThreadTest();        
        ThreadTest t3 = new ThreadTest();
        ThreadTest t4 = new ThreadTest();
            
        t1.start();
        t2.start();
        t3.start();
        t4.start();
                
    }

运行结果如下:

hread-0is saling ticket100
Thread-0is saling ticket99
Thread-0is saling ticket98
Thread-0is saling ticket97
Thread-0is saling ticket96
Thread-0is saling ticket95
Thread-1is saling ticket100
Thread-1is saling ticket99
Thread-1is saling ticket98
Thread-1is saling ticket97
Thread-1is saling ticket96
。。。。。。

从结果上看每个票号都被打印了四次,即四个线程各自卖各自的100张票,而不去卖共同的100张票。这种情况是怎么造成的呢?我们需要的是,多个线程去处 理同一个资源,一个资源只能对应一个对象,在上面的程序中,我们创建了四个ThreadTest对象,就等于创建了四个资源,每个资源都有100张票,每 个线程都在独自处理各自的资源。

使用实现Runnable接口方式现实:

public class RunableTest implements Runnable {
    
    private int ticket = 100;
    
    public void run(){
        
        while(true){
            if(ticket > 0){
                System.out.println(Thread.currentThread().getName() + "is saling ticket " + ticket--);
            }else{
                break;
            }
        }
    }
}

其对应测试类:

public class TestDemo {

    public static void main(String[] args) {

            RunableTest r  = new RunableTest();
        new Thread(r).start();
        new Thread(r).start();
        new Thread(r).start();
        new Thread(r).start();
    }

}    

运行结果:

。。。。
Thread-0is saling ticket 12
Thread-0is saling ticket 11
Thread-0is saling ticket 10
Thread-0is saling ticket 9
Thread-0is saling ticket 8
Thread-0is saling ticket 7
Thread-1is saling ticket 6
Thread-1is saling ticket 5
Thread-1is saling ticket 4
Thread-1is saling ticket 3
Thread-1is saling ticket 2
。。。。。

上面的程序中,创建了四个线程,每个线程调用的是同一个RunableTest对象中的run()方法,访问的是同一个对象中的变量 (ticket)的实例,这个程序满足了我们的需求。

可见,实现Runnable接口相对于继承Thread类来说,有如下显著的好处:

1、Runable接口适合多个相同的程序代码去处理同一个资源,即Runnable接口很容易实现资源共享,而Thread类不适合资源共享。

2、使用Runnable接口可以避免Java中单继承的限制。

3、增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

原文地址:https://www.cnblogs.com/conswin/p/6752099.html