深入浅出Java并发多线程(2)- 实现线程方式

1 实现多线程的方法有几种

  • 2种
    在这里插入图片描述

准确的说,创建线程只有一种方式就是构造 Thread 类,而实现线程的执行单元有两种方式。

  1. 实现 Runnable 接口的 run 方法,并把 Runnable实例传给 Thread
  2. 重写 Threadrun方法(继承 Thread 类)

public class RunnableStyle implements Runnable {

    public static void main(String[] args) {
        Thread thread = new Thread(new RunnableStyle());
        thread.start();
    }

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

public class ThreadStyle extends Thread {

    @Override
    public void run() {
        System.out.println("Thread类实现线程");
    }

    public static void main(String[] args) {
        new ThreadStyle().start();
    }
}

1.1 2种方法对比

  • 实现 Runnable 接口更好
  1. 从代码的架构去考虑,具体执行任务(run方法)应该和线程是解耦的
  2. 方法2每次去新建任务,只能新建一个独立的线程,这种损耗比较大,需要创建、执行和销毁;Runnable 就可以使用后续的线程池工具,减少创建线程带来的损耗;
  3. java不支持多继承了,继承了 Thread类,就无法继承其他类了,限制了可扩展性;

在这里插入图片描述

1.2 同时使用这2种方法

package threadcoreknowledge.createthreads;

/**
 * @Description 同时使用Thread 和 Runnable
 * @Author tzb
 * @Date 2020/11/25 22:59
 * @Version 1.0
 **/
public class BothRunnableThread {

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("来自 Runnable");
            }
        }){
            @Override
            public void run() {
                System.out.println("来自 Thread");
            }
        }.start();
    }
}

在这里插入图片描述

1.3 错误观点分析

1.3.1 线程池也是创建线程的方式

package threadcoreknowledge.createthreads.wrongways;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description TODO
 * @Author tzb
 * @Date 2020/11/29 11:03
 * @Version 1.0
 **/
public class ThreadPool5 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i = 0; i < 1000; i++) {
            service.submit(new MyTask() {
            });
        }
    }
}

class MyTask implements Runnable {

    @Override
    public void run() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    }
}

在这里插入图片描述

1.3.2 通过 CallableFutureTask 也是创建线程的方式

在这里插入图片描述

1.3.3 无返回值是实现 Runnable 接口,有返回值是实现 Callable 接口,所以 Callable 接口是新的实现线程的方式

1.3.4 定时器

package threadcoreknowledge.createthreads.wrongways;

import java.util.Timer;
import java.util.TimerTask;

/**
 * @Description 定时器创建线程
 * @Author tzb
 * @Date 2020/11/29 16:25
 * @Version 1.0
 **/
public class DemoTimmerTask {
    public static void main(String[] args) {
        final Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        },1000,100);
    }
}

1.3.5 匿名内部类

package threadcoreknowledge.createthreads.wrongways;

/**
 * @Description 匿名内部类
 * @Author tzb
 * @Date 2020/11/29 16:29
 * @Version 1.0
 **/
public class AnonymousInnerClassDemo {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }).start();

    }
}

在这里插入图片描述

1.3.6 Lambda表达式

package threadcoreknowledge.createthreads.wrongways;

/**
 * @Description lambda表达式创建线程
 * @Author tzb
 * @Date 2020/11/29 16:32
 * @Version 1.0
 **/
public class Lambda {
    public static void main(String[] args) {
        new Thread(()-> System.out.println(Thread.currentThread().getName())).start();
    }
}

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页