JUC之线程、线程池

这篇具有很好参考价值的文章主要介绍了JUC之线程、线程池。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、start与run方法

start方法开启一个新线程,异步执行。

run方法同步执行,不会产生新的线程。

start方法只能执行一次,run方法可以执行多次。

二、一些方法

sleep() 线程睡眠

两种方式调用:

Thread.sleep(1000);

TimeUnit.SECONDS.sleep(1);

线程打断

interrupt()这种方式打断,线程会抛出InterruptedException异常。比如在线程睡眠的时候,调用interrupt(),线程抛出异常。抛出InterruptedException异常的时候会清除中断标记。

interrupt()方法仅仅是将线程的中断状态设置为true,并不会停止线程。

thread.interrupt();

还有两个方法

isInterrupted()判断当前线程是否被打断,不会清除打断标记。

interrupted();判断当前线程是否被打断,清除打断标记,静态方法。清除打断标记就是恢复线程的 中断状态。也就是说,在调用Thread.interrupted()方法之后,如果中断了此线程,则不会抛出中断异常,但是如果第二次调用Thread.interrupted()方法的话直接返回false,除非有第二次中断触发。

boolean isInterrupted = thread.isInterrupted();

boolean interrupted = Thread.interrupted();

yield()线程让步

只是让出CPU资源,停止执行当前线程的动作,当前线程的状态回到可运行状态。但是当前线程做出让步以后,下一个CPU资源会在哪个线程的身上,取决去调度器,调度器会在同等优先级的线程之间选择一个分配资源。

设置/获取优先级

优先级设置越大,获得CPU资源的可能性就越高。默认优先级使5,最小1,最大10。

thread.setPriority(10);

int priority = thread.getPriority();

join()等待线程结束

join()

join(long time)

上述两个方法都是等待线程结束,即在执行的地方先等待子线程运行结束再往下继续运行主线程。带参数的是最大等待时间,时间一到则不再等待子线程,主线程继续往下运行。一些场景就是主线程运行依赖于子线程的运行结果。

isAlive()

当前线程是否存活

守护线程

线程分为守护线程和用户线程。默认为用户线程。

setDaemon(boolean on)设置当前线程为守护线程

isDaemon()判断当前线程是否为守护线程。

线程的几种状态和转换

JUC之线程、线程池,JAVA,java

创建线程的三种方式

1、继承Thread类

Thread t = new MyThread();
t.start();

public static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("my thread");
        }
}

这种方式是继承的方式,因为java是单继承,所以一般用的不多。

2、实现Runnable,重写run()方法

Thread t1 = new Thread(new RunnableThread());
t1.start();

public static class RunnableThread implements Runnable {
        @Override
        public void run() {
            System.out.println("runnable thread ... ");
        }
    }

这种实现接口的方式推荐使用

3、实现callable,重写call()方法

实现callable的方式,重写的call方法有返回值,这点和Runnable的接口有所不同,并且是交给FutureTask管理,通过future.get()可以获得call()方法的返回值。

注意的是,调用future.get()方法的时候,线程会等待call()方法执行完成,拿到返回值以后才会继续往下执行。

FutureTask futureTask = new FutureTask(new CallableThread());
futureTask.run();
String res = (String) futureTask.get();


public static class CallableThread implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("callable thread ... ");
            TimeUnit.SECONDS.sleep(5);
            return "callable";
        }
    }

如果不需要返回值的话,用的最常见的就是第二种实现Runnable的方式,并且用lambda的方式,比如:

new Thread(()->{
            System.out.println("thread start ...");
        }).start();

线程池

集中管理线程,节省资源,线程复用,减少开销,便于维护。

Executors提供了固定的几种线程池的创建方式。

1、Executors.newFixedThreadPool(5);创建固定大小的线程池,参数是线程数量

2、Executors.newSingleThreadExecutor();创建只有一个线程数量的线程池
3、Executors.newCachedThreadPool();创建可以扩容的线程池,会一直增加线程数量,不建议使用。

上述3中线程池执行方法:

executorService.execute(()->{});传入Runnable对象

4、Executors.newScheduledThreadPool(5);创建有定时任务的线程池

这种线程池执行的方式scheduledExecutorService.schedule(()->{},5,TimeUnit.SECONDS);

第一个参数是Runnable对象,第二个参数是延迟时间,第三个参数是时间单位。

关闭线程池

shutdown(),等待所有的任务执行完毕关闭线程池。

shutdownNow(),等待正在执行的任务执行完毕后关闭线程池。

awaitTermination(10, TimeUnit.SECONDS),等待所有任务执行完毕,或者超时以后线程池关闭

isTerminated()线程池是否关闭

线程池的execute和submit方法区别

1、参数不同

execute()方法接收的是Runnable参数

submit接收的是Runnable或者Callable参数

2、返回值不同

execute()方法没有返回值

submit方法有返回值,返回的是Future类型,通过future.get()获得具体的结果。

注意:如果execute传入的是FutureTask类型的话,其实也是可以接收返回结果的。只不过submit替我们封装了FutureTask。

ExecutorService executorService = Executors.newFixedThreadPool(5);
Future<String> future = executorService.submit(() -> {
      return "123";
 });
 String s = future.get();
 System.out.println("s " + s);



 FutureTask<String> futureTask = new FutureTask(() -> {
      return "hello";
 });
 executorService.execute(futureTask);
 System.out.println("futuretask " + futureTask.get());

3、异常捕捉

execute()执行的子线程中的异常,只能子线程进行处理,主线程无法处理,即无法进行 程序的统一异常处理。

submit()中子线程的异常可以在主线程中进行统一异常处理,因为子线程出现异常的时候,并不会立即报错,在进行future.get()进行获取结果的时候才抛出异常,所以主线程可以进行统一异常处理。

自定义线程池

参数

corePoolSize:核心线程数

maximumPoolSize:最大线程数

keepAliveTime:非核心线程空闲状态存活时间

unit:存活时间单位

workQueue:工作/阻塞队列,

线程先加入到核心线程,核心线程数量达到以后,就会加入到阻塞队列,当阻塞队列满了以后加入非核心线程。

threadFactory:线程工厂

handler:拒绝策略

当线程已经超过了最大线程数加上阻塞队列的数量,就会触发拒绝策略

有四种拒绝策略:

AbortPolicy:拒绝新任务并抛出异常

DiscardPolicy:丢弃任务,不会抛异常

DiscardOldestPolicy:丢弃老的未处理的任务,新的任务加入队列

CallerRunsPolicy:自己处理新的任务,处理的逻辑在传入的Runnable方法中实现。文章来源地址https://www.toymoban.com/news/detail-859341.html

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                3,
                0,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        try {
            for (int i = 0; i < 50; i++) {
                Task task = new Task(i);
                threadPoolExecutor.submit(task);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPoolExecutor.shutdown();
        }
public static class Task implements Runnable {
        int i;

        public Task(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread: "+Thread.currentThread().getName()+" ... ...");
        }
    }

到了这里,关于JUC之线程、线程池的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java|多线程与高并发】JUC中常用的类和接口

    JUC是Java并发编程中的一个重要模块,全称为 Java Util Concurrent (Java并发工具包),它提供了一组用于多线程编程的工具类和框架,帮助开发者更方便地编写线程安全的并发代码。 本文主要介绍 Java Util Concurrent 下的一些常用接口和类 Callable接口类似于Runnable. 有一点区别就是

    2024年02月12日
    浏览(33)
  • 【JavaEE】JUC(java.util.concurrent)的常见类以及线程安全的集合类

    目录 1、JUC(java.util.concurrent)的常见类 1.1、Callable接口的用法(创建线程的一种写法)  1.2、ReentrantLock可重入互斥锁 1.2.1、ReentrantLock和synchronized的区别  1.2.2、如何选择使用哪个锁 1.3、Semaphore信号量 1.4、CountDownLatch  2、线程安全的集合类 2.1、多线程环境使用ArrayList  2.2、

    2024年02月07日
    浏览(49)
  • Java并发工具合集JUC大爆发!!!

    通常我们所说的并发包也就是java.util.concurrent(JUC),集中了Java并发的各种工具类, 合理地使用它们能帮忙我们快速地完成功能 。 作者: 博学谷狂野架构师 GitHub: GitHub地址 (有我精心准备的130本电子书PDF) 只分享干货、不吹水,让我们一起加油!😄 CountDownLatch是一个同步计

    2023年04月17日
    浏览(81)
  • 剑指JUC原理-8.Java内存模型

    👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家 📕系列专栏:Spring源码、JUC源码 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 🍂博主正在努力完成2023计划中:源码溯源,一探究竟 📝联系方式:nhs19990716,加我进群

    2024年02月06日
    浏览(50)
  • java JUC并发编程 第六章 CAS

    第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七章 java JUC并发编程 原子操作类增强: link 第八章

    2024年02月10日
    浏览(48)
  • Java开发 - 不知道算不算详细的JUC详解

    大概有快两周没有发文了,这段时间不断的充实自己,算算时间,也到了该收获的时候,今天带来一篇JUC详解,但说实话,我也不敢自信它详不详细。JUC说白了就是多线程,学Java不久的人知道多线程,恐怕还不知道JUC是什么。在这篇博客中,博主将对JUC做一个自认为比较全面

    2024年02月06日
    浏览(48)
  • 【JavaEE】JUC(Java.util.concurrent)常见类

    经过前面文章的学习我们大致了解了如何实现多线程编程和解决多线程编程中遇到的线程不安全问题, java.util.concurrent 是我们多线程编程的一个常用包,那么今天我将为大家分享 java.util.concurrent 包下的其他几种常见的类。 ReentrantLock 是可重入互斥锁,跟 synchronized 定位是类似

    2024年02月08日
    浏览(41)
  • 【JUC进阶】03. Java对象头和内存布局

    为了后面更好的学习锁优化以及运作过程,需要我们对HotSpot虚拟机的Java对象内存布局有一定的了解,也作为技术储备。 在HotSpot虚拟机中,对象在堆内存中存储的布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)。 而数组对象和普通对

    2024年02月10日
    浏览(45)
  • 【JAVAEE】JUC(java.util.concurrent)的常见类

    目录 1.Callable接口 1.1简介 1.2代码演示  1.3Runnable与Callable的区别 2.ReentrantLock 2.1ReentrantLock的常用方法 2.2ReentrantLock的代码演示 2.3ReentrantLock和synchronized的区别 3.Semaphore信号量 3.1概念 3.2代码演示 4.CountDownLatch 4.1概念 4.2代码演示 JUC是java.util.concurrent包的简称,JDK1.5之后对多线程的

    2024年02月05日
    浏览(40)
  • java JUC并发编程 第九章 对象内存布局与对象头

    第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七章 java JUC并发编程 原子操作类增强: link 第八章

    2024年02月07日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包