Java多线程实现的三种方法

继承Thread类实现多线程

Java.lang.Thread是线程操作的核心类,新建一个线程最简单的方法就是直接继承Thread类,而后覆写run()方法。

//继承Thread类实现多线程



//线程主体类
class MyThread extends Thread{
    private String title;

    public MyThread(String title) {
        this.title = title;
    }

    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            System.out.println(this.title+",i="+i);
        }
    }
}

public class Test {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread("Thread1");
        MyThread myThread2 = new MyThread("Thread2");
        MyThread myThread3 = new MyThread("Thread3");
        myThread1.start();
        myThread2.start();
        myThread3.start();


    }
}

实现Runnable接口实现多线程

启动一个线程就要调用start()方法,但是Runnable接口中没有start()方法,该怎么办呢?

实际上,虽然Runnable接口中没有start()方法,但是start()方法在Thread类中,并且Thread类实现了Runnable接口,所以我们可以通过向Thread类的构造方法中传一个Runnable接口对象来调用start()方法,启动多线程。



//Runnable接口实现多线程

//class Thread implements Runnable 所以 public Thread(Runnable target) 可以接收Runnable接口对象

//利用Runnable接口实现线程主体类

class MyThread1 implements Runnable{
    private String title;

    public MyThread1(String title) {
        this.title = title;
    }

    @Override
    public void run() {
       for(int i = 0; i < 10; i++){
           System.out.println(this.title+",i="+i);
       }
    }
}


//启动多线程

public class Test1 {
    public static void main(String[] args) {
        MyThread1 myThread1a = new MyThread1("myThread1a");//Runnable接口对象
        MyThread1 myThread1b = new MyThread1("myThread1b");
        MyThread1 myThread1c = new MyThread1("myThread1c");
        //Thread 匿名内部类
        new Thread(myThread1a).start();
        new Thread(myThread1b).start();
        new Thread(myThread1c).start();


        }
}

实现Callable接口实现多线程

Java.util.concurrent.Callable是JDK1.5新增的高并发程序编程包。

要实现多线程,首先要实现Callable,然后覆写call()方法,接口的返回值用Future接口的get()方法来接收。



//Callable实现多线程

//使用Callable定义线程主体类

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyThread5 implements Callable{
    private int ticket = 10;

    @Override
    public String call() {
        while(this.ticket > 0){
            System.out.println("剩余票数"+this.ticket--);
        }
        return "票卖完了";
    }
}

/*
要把一个Callable对象启动,核心类是FutureTask,它既是Runnable的子类也是Future的子类,但是它能传进来一个
Callable的对象,所以FutureTask这个类打通了Thread类和MyThread类
 */
public class Test5 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask task = new FutureTask<>(new MyThread5());
        new Thread(task).start();
        new Thread(task).start();
        new Thread(task).start();
        System.out.println(task.get());

    }
}

注意:

无论那种方式实现多线程,程序启动一定调用的是Thread类的start()方法!!!

一个线程的start()方法只能调用一次,多次调用报java.lang.IllegalThreadstateException错误。

分析:

Thread类实现多线程与实现Runnable接口实现多线程都要覆写run()方法,二者有何关系呢?

第一点就是Thread类与自定义线程类(实现了Runnable接口),是一个典型的代理设计模式,Thread类负责辅助真实业务操作(资源调度,创建线程并启动),自定义线程类负责真实业务的实现。

第二点使用Runnable接口实现的多线程程序可以更好地描述共享的概念。

第三点Thread类有单继承的缺点,Runnable接口可以多实现。

你可能感兴趣的:(Java多线程实现的三种方法)