两种方式创建多线程

线程编程–两种方式创建多线程

目的

创建线程,即拿到一个线程实例。这个线程实例必须具备开启、等待、唤醒等控制自身生命周期的方法。

创建线程

为什么Java要提供两种方法来创建线程呢?它们都有哪些区别?相比而言,哪一种方法更好呢?

1. 在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。
2. 还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.
  
* 假设一个影院有三个售票口,
* 分别用于向儿童、成人和老人售票。
* 影院为每个窗口放有100张电影票,
* 分别是儿童票、成人票和老人票。三个窗口需要同时卖票,
* 而现在只有一个售票员,这个售票员就相当于一个CPU,三个窗口就相当于三个线程。
* 通过程序来看一看是如何创建这三个线程的。
#### 方式一:通话继承Thread类

public class MutliThread extends Thread {
    private int ticket = 100;
    private String name;
    public MutliThread(){}

    public MutliThread(String name){
            super(name);
    }

    @Override
    public void run() {
        while (ticket>0){
            System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
        }
    }
}
1 public class MutliThreadDemo {
 2     public static void main(String[] args) {
 3         MutliThread m1=new MutliThread("Window 1"); 
 4         MutliThread m2=new MutliThread("Window 2"); 
 5         MutliThread m3=new MutliThread("Window 3"); 
 6         m1.start();
 7         m2.start();
 8         m3.start();
 9     }
10 }

 程序中定义一个线程类,它扩展了Thread类。利用扩展的线程类在MutliThreadDemo类的主方法中创建了三个线程对象,并通过start()方法分别将它们启动。

从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系,因此都有机会得到CPU的处理。

但是结果显示这三个线程并不是依次交替执行,而是在三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,而有的线程被分配时间片的机会比较少,票迟一些卖完。

  可见,利用扩展Thread类创建的多个线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。
  
#### 方式二:通过实现Runnable接口来创建多线程

public class MutliRunnable implements Runnable {
    private int ticket = 100;
    private String name;
// 三个资源的时候写该方法
//    public MutliRunnable(String name){
//        this.name = name;
//    }

    @Override
    public void run() {
        while (ticket>0){
//            System.out.println(ticket--+" is saled by "+name);
            System.out.println(ticket--+" is saled by "+ Thread.currentThread());
        }
    }
}
public class MutliThreadDemo {

    public static void main(String args[]){
        //测试继承Thread创建多线程
//        MutliThread m1 = new MutliThread("Windows 1");
//        MutliThread m2 = new MutliThread("Windows 2");
//        MutliThread m3 = new MutliThread("Windows 3");
//        m1.start();
//        m2.start();
//        m3.start();
        //测试实现Runnable接口创建多线程
        //三个资源 每个资源三百张票
       MutliRunnable m1 = new MutliRunnable("Windows 1");
        MutliRunnable m2 = new MutliRunnable("Windows 2");
        MutliRunnable m3 = new MutliRunnable("Windows 3");
        Thread t1= new Thread(m1);
        Thread t2= new Thread(m2);
        Thread t3= new Thread(m3);

        //一个资源 一百张票共享 只能用实现Runnable接口来实现
//        MutliRunnable m = new MutliRunnable();
//        Thread t1= new Thread(m);
//        Thread t2= new Thread(m);
//        Thread t3= new Thread(m);
//        t1.start();
//        t2.start();
//        t3.start();
    }

}

由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和 1 结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。

  可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
  

通过实现Runnable接口来实现线程间的资源共享
public class MutliRunnable implements Runnable {
    private int ticket = 100;
// 三个资源的时候写该方法
    public MutliRunnable(String name){
        this.name = name;
        }
}
public class MutliThreadDemo {

    public static void main(String args[]){
        //测试继承Thread创建多线程
//        MutliThread m1 = new MutliThread("Windows 1");
//        MutliThread m2 = new MutliThread("Windows 2");
//        MutliThread m3 = new MutliThread("Windows 3");
//        m1.start();
//        m2.start();
//        m3.start();
        //测试实现Runnable接口创建多线程
        //三个资源 每个资源三百张票
//        MutliRunnable m1 = new MutliRunnable("Windows 1");
//        MutliRunnable m2 = new MutliRunnable("Windows 2");
//        MutliRunnable m3 = new MutliRunnable("Windows 3");
//        Thread t1= new Thread(m1);
//        Thread t2= new Thread(m2);
//        Thread t3= new Thread(m3);

        //一个资源 一百张票共享 只能用实现Runnable接口来实现
        MutliRunnable m = new MutliRunnable();
        Thread t1= new Thread(m);
        Thread t2= new Thread(m);
        Thread t3= new Thread(m);
        t1.start();
        t2.start();
        t3.start();
    }

}

结果正如前面分析的那样,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。

  可见,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。而这一功能通过扩展Thread类是无法实现的,读者想想看,为什么?

  实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。这种方式不仅有利于程序的健壮性,使代码能够被多个线程共享,而且代码和数据资源相对独立,从而特别适合多个具有相同代码的线程去处理同一资源的情况。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值