Java多线程实现

1.继承Thread类实现多线程

java.lang.Thread是一个线程操作的核心类。新建一个线程最简单的方法就是直接继承Thread类,而后覆写该类中的run()方法(就相当于主类中的main方法)。

直接调用run方法:

public class testThread {
    public static void main(String[] args) {
       MyThread myThread1 = new MyThread("MyThread1");
       MyThread myThread2 = new MyThread("MyThread2");
       MyThread myThread3 = new MyThread("MyThread3");
       //普通的run方法无法启动线程,不能直接调用run方法
       myThread1.run();
        myThread2.run();
        myThread3.run();
    }
}
 class MyThread extends Thread {

    private String title;

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

    public void run() {
        System.out.println("run 开始");//1
        for (int i = 0; i < 10; i++) {//2
            System.out.println(this.title + "  " + i);
        }
        System.out.println("run 结束");//3
    }

}

但是直接调用run方法只能顺序打印,无法实现多线程的交替打印。真正实现多线程的方法时Thread类中的start()方法来间接调用run()方法。

利用start方法实现多继承:

public class testThread {
    public static void main(String[] args) {

        System.out.println("这是主方法开始");//1

        MyThread myThread1 = new MyThread("MyThread1");
       MyThread myThread2 = new MyThread("MyThread2");
       MyThread myThread3 = new MyThread("MyThread3");
       //普通的run方法无法启动线程,不能直接调用run方法
       // myThread1.run();
       // myThread2.run();
       // myThread3.run();
        // start()此方法会自动调用线程的run()方法
        myThread1.start();
        myThread2.start();
        myThread3.start();
        //for (int i = 0; i < 10; i++) {//3
        //    System.out.println("这是主方法的循环:" + i);
        //}
        // myThread1.start();
        //System.out.println("这是主方法结束");//4

    }
}
 class MyThread extends Thread {

    private String title;

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

    public void run() {
        System.out.println("run 开始");//1
        for (int i = 0; i < 10; i++) {//2
            System.out.println(this.title + "  " + i);
        }
        System.out.println("run 结束");//3
    }

}

start()函数调run()函数关系图如下:
Java多线程实现
继承Thread类实现多线程总结如下:
1.1 自定义类继承java.lang.Thread类,覆写run方法;
1.2 实例化自定义类对象,该对象就是一个具备线程执行的对象;
1.3 线程类的对象run方法直接调用和普通类的对象调用没有区别;
1.3.1直接调用run方法,实际还是同步执行,跟线程没关系;
1.3.2 调用start方法,才会异步执行,跟线程有关系,该方法不能多次调用;
1.4 native修饰的方法称为本地方法,需要依赖平台实现 JNI(Java Native Interface);

2.Runnable()接口实现多线程

首先利用Runable()接口实现线程主体类:

class MyRunnable implements Runnable {

    private String title;
    MyRunnable(String title) {
        this.title = title;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.title + " " + i);
        }
    }
}

接下来启动多线程,多线程的启动永远都是Thread类的start()方法。
Thread类对Runnable接口的实现类提供的构造方法:

public Thread(Runnable target)

完成多线程实现如下:

public class testThread2 {
    //使用Lamada表达式
    public static void code2(){
        System.out.println("main开始");
        Thread myThread = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("runnable " + i);
            }
        });
        myThread.start();//start()->start0()->run()->target.run()->runnable.run()
        for (int i = 0; i < 10; i++) {
            System.out.println("main " + i);
        }
        System.out.println("main结束");
    }
    //使用Runnable接口实现多继承
    public static void code3(){
        System.out.println("main开始");
        Runnable runnable = new MyRunnable("MyRunnable");

        //Thread类提供的构造方法:
        //public Thread(Runnable target)
        //可以接收Runnable接口对象
        Thread myThread1 = new Thread(runnable);
        myThread1.start();
        Thread myThread2 = new Thread(runnable);
        myThread2.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("main " + i);
        }
        System.out.println("main结束");
    }

    public static void main(String[] args) {

        //1.Runnable     代理接口
        //2.MyRunnable implements Runnable  业务类
        //3.Thread     implements Runnable  代理类
        //  Runnable实现多线程就是一个典型的代理模式
    }
}
class MyRunnable implements Runnable {

    private String title;
    MyRunnable(String title) {
        this.title = title;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.title + " " + i);
        }
    }
}

Runnable()接口实现多线程(业务无返回结果):
2.1 自定义类实现java.lang.Runnable接口,实现run方法;
2.2 实例化Thread类对象,通过构造方法传入Runnable接口的实现类的实例化对象或者一个Lambda表达式;
2.3 线程的启动方式start;
2.4解决Thread的继承缺陷,实现多接口;

3.Callable实现多线程

Callable实现多线程适合进行高并发编程,其可以实现返回值结果。

Callable实现多线程:

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

public class testCallable {
    public static void main(String[] args) {
        Callable<String>   callable=new MyCallable();
        //将来的任务
        //FutureTask 包装 Callable接口实现类的对象
        FutureTask<String> futureTask=new FutureTask<>(callable);
        Thread  thread=new Thread(futureTask);
        thread.start();
        System.out.println("main 代码");
        System.out.println("main 代码");
        System.out.println("main 代码");

        try {
            //阻塞方法 获取线程执行的结果
            String string = futureTask.get();
            System.out.println(string);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }


    }
}
class MyCallable implements Callable<String> {
    private int tick = 10;
    public String call() throws Exception {
        while (this.tick > 0) {
            System.out.println("剩余:" + --this.tick + " 票");
        }
        return "票卖完啦";
    }
}

Callable实现多线程总结(业务有返回结果):
3.1 自定义类实现java.util.concurrent.Callable接口,实现call方法;
3.2 FutureTask 包装 Callable接口实现类的对象;
3.3 实例化Thread类对象,通过构造方法传入FutureTask对象;
3.4 通过Thread对象的start方法启动线程;
3.5 通过FutureTask对象的get方法获取结果(阻塞方法);