并发编程(壹):建立线程的三种方式及其对比

建立线程的三种方式及其对比


1. 继承 Thread类

(1). 继承Thread类。并重写run()方法,该方法无参数,无返回值;java

(2). 建立子类实例,并实例化对象;编程

(3). 经过start()方法启动,注意:不是经过run()方法启动。多线程

public class ThreadDemo extends Thread{
    public void run(){
        System.out.println("继承Thread建立线程的.");
    }
}

public class ThreadAction {
    public static void main(String[] args) {
        Thread threadDemo=new ThreadDemo();
        threadDemo.start();
    }
}

2. 实现Runnable接口

(1). 实现Runnable接口,并从新run()方法;ide

(2). 建立Runnable实现类的实例,并用这个实例做为Thread的target建立线程对象;this

(3). 经过start()启动线程。线程

public class RunnableDemo implements Runnable{

    @Override
    public void run() {
        System.out.println("实现Runnable建立线程的.");
    }
}

public class ThreadAction {
    public static void main(String[] args) {
        RunnableDemo runnableDemo = new RunnableDemo();
        Thread thread = new Thread(runnableDemo);
        thread.start();
    }
}

3. 经过Callable和Future建立线程

产生背景:这种建立线程的方式在jdk1.5后出现,目的是弥补上面两种建立线程方式,其中的run()方法不能有返回值,不能抛出异常等问题。code

(1). 建立实现Callable的实现类,并实现call()方法;对象

(2). 建立该实现类的实例(从java8开始能够直接使用Lambda表达式建立Callable对象);继承

(3). 使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值;接口

(4). 使用FutureTask对象做为Thread对象的target建立并启动线程(由于FutureTask实现了Runnable接口);

(5). 调用FutureTask对象的get()方法来得到子线程执行结束后的返回值。

public class CallableDemo implements Callable<String> {
    
    @Override
    public String call() throws Exception {
        return "hello ,我是经过实现Callable接口的方式建立线程。";
    }
}

public class ThreadAction {
    public static void main(String[] args) {
        CallableDemo callableDemo = new CallableDemo();
        // 使用FutureTask类来包装Callable对象
        FutureTask<String> stringFutureTask = new FutureTask<>(callableDemo);
        Thread thread = new Thread(stringFutureTask);
        thread.start();
        try {
            System.out.println(stringFutureTask.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

4. 建立线程的三种方式的对比

实现Runnable、Callable接口的方式建立多线程

  • 优点:该线程只是实现了接口,还能够继承其余类.在这种方式下多个线程共享一个target对象,因此很是适合多个相同线程来处理同一份资源的状况,从而能够将CPU、代码和数据分开,造成清晰的模型,较好地体现了面向对象的思想.
  • 劣势:编程稍微复杂,若是要访问当前线程,则必须使用Thread.currentThread()方法。

继承Thread类

  • 优点:代码编写简单,当前Thread可用this获取.
  • 劣势:继承Thread类,不可继承其余类.
相关文章
相关标签/搜索