Java基础——多线程(二)——创建线程的两种方式及区别

创建线程有两种方法:

  • 需要从Java.lang.Thread类派生一个新的线程类,重写它的run()方法; 
  • 实现Runnalbe接口,重载Runnalbe接口中的run()方法。

一、将类声明为Thread的子类。该子类应重写Thread 类的 run 方法(线程之间相互独立,不可共享资源)。接下来可以分配并启动该子类的实例。

例如,计算大于某一规定值的质数的线程可以写成:

 

     class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

然后,下列代码会创建并启动一个线程:

     PrimeThread p = new PrimeThread(143);
     p.start();

代码示例:

class Demo_01 extends Thread{
    private String name;
    Demo_01(String name){
        super(name);
        //this.name = name;
    }

    public void run(){
        for(int x = 0; x < 10; x++){
            for (int y = 0; y < 7777777; y++){}
            System.out.println("..."+"x="+x+"..."+Thread.currentThread().getName());
        }
    }
}

public class Test_01 {

    public static void main(String[] args) {

        Demo_01 d1 = new Demo_01("张三");
        Demo_01 d2 = new Demo_01("lisi");
        d1.start();
        d2.start();
    }
}

二、声明实现 Runnable 接口的类(实现Runable接口)。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。(可以线程之间相互独立,不可共享资源。也可以所有线程共享同一资源)

采用这种风格的同一个例子如下所示:

 

     class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

然后,下列代码会创建并启动一个线程:

     PrimeRun p = new PrimeRun(143);
     new Thread(p).start();

代码示例:

//一、线程独立拥有资源,互不影响
class Demo_02 implements Runnable{

    public void run(){
        show();
    }

    private void show() {
        for (int i = 0; i < 20; i++){
            System.out.println(Thread.currentThread().getName()+"..."+i);
        }
    }
}

public class Test_02 {
    public static void main(String[] args) {
        Demo_02 d1 = new Demo_02();
        Demo_02 d2 = new Demo_02();

        Thread t1 = new Thread(d1);
        Thread t2 = new Thread(d2);
        t1.start();
        t2.start();
    }
}

//二、线程共享资源
class Demo_02 implements Runnable{

    private int i = 20;
    public void run(){
        show();
    }
    private void show() {
        while(i > 0){
            System.out.println(Thread.currentThread().getName()+"..."+i);
        }
    }
}

public class Test_02 {
    public static void main(String[] args) {
        Demo_02 d = new Demo_02();

        Thread t1 = new Thread(d);
        Thread t2 = new Thread(d);
        t1.start();
        t2.start();
    }
}

每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

上述内容详见Java JDK API 文档

两种创建方式的区别

在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。

  还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.

通过扩展Thread类来创建多线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。

通过实现Runnable接口来创建多线程,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。

详见:Java中实现多线程两种方式之间的区别

 

posted on 2020-02-11 11:39  青山是谁  阅读(46)  评论(0编辑  收藏  举报