【多线程 - 02、创建线程】

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。

继承Thread类创建线程类

1、定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此经常把run()方法称为线程执行体。

2、创建Thread子类的实例,即创建了线程对象

3、调用线程对象的start()方法就可以告知启动该线程

public class ThreadTest {
    public static void main(String[] args) {
        for (int i = 1;i<15;i++){//主线程名:main
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
            if (i == 5){
                //start方法通知线程可以启动运行
                new Test().start();//线程名字:Thread-0
                new Test().start();//线程名字:Thread-1
            }
        }
    }
}
class Test extends Thread{
    @Override
    public void run() {
        super.run();
        for (int i = 1;i<=10;i++){
            System.out.println("线程名字:"+this.getName()+"-"+i);
        }
    }
}
//结果会出现主线程和两个子线程交错打印出结果

实现Runnable接口创建线程类

1、定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体也称之为线程方法执行体。

2、创建Runnable实现类的实例,并将此实例作为形参传入new Thread()的构造函数中,就可创建Thread线程对象

public class ThreadTest {
    public static void main(String[] args) {
        for (int i = 1;i<15;i++){//主线程名:main
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
            if (i == 5){
                //start方法通知线程可以启动运行
                //也可以使用匿名内部类实现
                new Thread(new Test(),"线程名1").start();
                new Thread(new Test(),"线程名2").start();
            }
        }
    }
}
class Test implements Runnable{
    @Override
    public void run() {
        for (int i = 1;i<=10;i++){
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
        }
    }
}
//结果会出现主线程和两个子线程交错打印出结果

使用Callable和Future创建线程

1、创建Callable接口的实现类,重写call()方法 ,该方法就是线程方法执行体,call()方法有返回值,再创建Callable实现类的实例。

2、使用FutureTask类的实例,来包装Callable对象,即把callable的实例以形参的方式传入new FutureTask()的构造函数中

3、使用FutureTask对象作为Thread对象的target创建启动线程。

4、通过FutureTask实例对象调用get()方法得到子线程的返回值。

public class ThreadTest {
    public static void main(String[] args) {
        Test test = new Test();
        FutureTask<Double> task1 = new FutureTask(test);
        FutureTask<Double> task2 = new FutureTask(test);

        for (int i = 1;i<15;i++){//主线程名:main
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
            if (i == 5){
                //start方法通知线程可以启动运行
                new Thread(task1,"线程名1").start();
                new Thread(task2,"线程名2").start();
            }
        }
        try {
            Double rs1 = task1.get();//返回值会等子线程运行完后获得
            Double rs2 = task2.get();
            System.out.println(rs1+"-----"+rs2);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
class Test implements Callable {
    @Override
    public Object call() throws Exception {
        for (int i = 1;i<15;i++){
            System.out.println("线程名字:"+Thread.currentThread().getName()+"-"+i);
        }
        return Math.random();
    }
}
//结果会出现主线程和两个子线程交错打印出结果

创建线程的三种方式对比

使用实现Runnable 、Callable接口的方式创建多线程

优点:
线程类只是实现了Runnable接口或Callable接口,同时还可以继承其他类。
多个线程可以共享一个target对象,非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码、数据分开,形成清晰的模型,较好的体现了面向对象的思想

缺点:
编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。

使用继承Thread类的方式创建多线程

优点:
编写简单,如果要访问当前线程,无需使用Thread.currentThread()方法,可以直接使用this的方式获取当前线程

缺点:
因为线程类已经继承了Thread类,所以不能再继承其他的父类。

项目中推荐使用Runnable接口或Callable接口创建多线程。

你可能感兴趣的:(多线程,java,开发语言,多线程)