IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Java 线程创建的四种方式 -> 正文阅读

[移动开发]Java 线程创建的四种方式

Java 线程创建的四种方式

所有测试用例使用的是 jdk8 ,版本不同可能会有所不同,建议自己亲手试试。

Thread 方式

通过继承Thread类来创建新的线程(不推荐)。示例如下:

创建类

public class ThreadDemo extends Thread {
    private Logger logger = LoggerFactory.getLogger(ThreadDemo.class);
    @Override
    public void run() {
        logger.info("Thread方式创建线程");
    }
}

测试方法

@Test
public void testThread(){
    new ThreadDemo().start();
}

注意:

如果一个继承Thread的类的实例对象,调用两次start()方法,会报异常。

示例:

@Test
public void testThread(){
    ThreadDemo threadDemo = new ThreadDemo();
    threadDemo.start();
    threadDemo.start();
}

报错:

java.lang.IllegalThreadStateException

在线程创建之后,java 底层会记录线程的状态,第一次调用就会改变状态,再次调用就会报异常

public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

Runnable 方式

通过实现Runnable接口来创建线程。

示例如下:

创建类:

public class RunnableEntity implements Runnable {
    private Logger logger = LoggerFactory.getLogger(RunnableEntity.class);
    @Override
    public void run() {
        logger.info("Runnable方式创建线程");
    }
}

测试方法:

@Test
public void testRunnable(){
    new Thread(new RunnableEntity()).start();
}

使用匿名内部类创建接口:

测试方法:

@Test
public void testRunnableAnonymous (){
    new Thread(new Runnable() {
        @Override
        public void run() {
            logger.info("Runnable方式创建线程,使用匿名内部类");
        }
    }).start();
}

Thread和Runnable区别:

  • Thread 是类,需要继承,但是一个类只能继承一个类,一旦继承 Thread 之后,无法在继承其他的类。
  • Runnable 是接口,一个类可以实现多个接口,所以实现Runnable接口可拓展性更好
  • Thread是Runnable接口的实现类

Callable 方式

通过实现Callable接口来创建线程。

创建类:

public class CallableEntity implements Callable<String> {
    private Logger logger = LoggerFactory.getLogger(CallableEntity.class);

    @Override
    public String call() throws Exception {
        return "Callable方式创建线程,这个可以带返回值,撒浪嘿呦";
    }
}

测试方法:

@Test
public void testCallable () throws ExecutionException, InterruptedException {
    FutureTask<String> stringFutureTask = new FutureTask<>(new CallableEntity());
    new Thread(stringFutureTask).start();
    logger.info("返回值信息:{}", stringFutureTask.get());

}

匿名内部类:

@Test
public void testCallableAnonymous () throws ExecutionException, InterruptedException {
    FutureTask<String> stringFutureTask = new FutureTask<>(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return "Callable方式创建线程,匿名内部类";
        }
    });
    new Thread(stringFutureTask).start();
    logger.info("返回值信息:{}", stringFutureTask.get());

}

Runnable和Callable的区别

  • Runnable没有返回值。
  • Callable可以返回值。

线程池方式

自定义线程池(推荐),从中获取线程。

@Test
public void testExecutor () throws ExecutionException, InterruptedException {
    ExecutorService executorService = new ThreadPoolExecutor(5, 9, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
    for (int i = 0; i < 5; i++){
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                logger.info("当前线程名称:{}", Thread.currentThread().getName());
            }
        });
    }
}

参数说明,只是大致表明,后续会补链接,大家也可以自行搜索。

public ThreadPoolExecutor(int corePoolSize, //核心线程数
                              int maximumPoolSize, //最大线程数
                              long keepAliveTime, //空闲线程存活时间
                              TimeUnit unit, // 时间单位,秒,分,天等
                              BlockingQueue<Runnable> workQueue, //阻塞队列,存放任务
                              ThreadFactory threadFactory, //线程工厂,一般使用默认的
                              RejectedExecutionHandler handler //拒绝策略
                         ) {

使用Executor接口对应的工具类Executors(不推荐):

FixedThreadPool:可定长线程池。

@Test
public void testExecutorsFix () throws InterruptedException, ExecutionException {
    ExecutorService executorService = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 5; i++){
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                logger.info("FixedThreadPool,当前线程:{}", Thread.currentThread().getName());
            }
        }).get();
    }
}

Executors还有其他的线程池,可以自己尝试。

  • WorkStealingPool

  • ScheduledThreadPool

  • CachedThreadPool

  • SingleThreadExecutor

  • SingleThreadScheduledExecutor

注意:

使用Executors工具类创建的线程池,FixedThreadPool、SingleThreadPool、CachedThreadPool默认阻塞队列是Integer.MAX_VALUE,不推荐使用。推荐使用自定义线程池,ThreadPoolExecutor,选择合适的阻塞队列的长度。

CompletionService方式
用来提升线程带返回值的效率。

  • 使用 Executors工具类 创建的线程池和 ThreadPoolExecutor 创建的线程池,如果需要获取线程的返回值,获取线程的返回值是顺序的,导致有些线程已经执行完,但是正在执行的线程还没获取返回值,则会进行等待,所以效率提升不是很高。
  • 使用CompletionService方式,则是哪个线程先执行完之后,哪个线程先获取数据。

代码示例:

@Test
public void testExecutorCompletionCallable () throws InterruptedException, ExecutionException {

    CompletionService<String> completionService = new ExecutorCompletionService<>(Executors.newFixedThreadPool(5));
    for (int i = 0; i < 5; i++){
        int finalI = i;
        completionService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                logger.info("第几次循环:{}", finalI);
                return "返回结果:" + finalI;
            }
        });

        //logger.info("get:{}", completionService.take().get());
    }
    for (int j = 0; j < 5; j++){
        logger.info("get:{}", completionService.take().get());
    }

}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:12:56  更:2022-03-06 13:13:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 16:48:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码