java中的线程通讯和线程池,Callable任务

news2024/11/24 17:22:46

线程通讯:
在多线程中,某个线程进入“等待状态”时,需要某个线程来唤醒

等待方法:
wait()//无线等待

wait(long 毫秒)//计时等待

注意,调用wait方法,会自动释放掉锁资源

处于wait状态只能由其他线程唤醒

唤醒方法:
notify();//唤醒处于“等待状态”的任意一个线程,和notify使用相同锁对象的线程

notifyAll();//唤醒处于“等待状态”的所有线程

注意,调用notify(),notifyAll()方法,不会自动释放掉锁资源

使用细节:

等待和唤醒的方法,都要使用锁对象调用需要在同步代码块中使用

等待和唤醒方法都应该使用相同的锁对象调用

消费者,生产者模型:

//共享资源
public class Resource {
    static public int number=0;
}
public class test2 {
    public static void main(String[] args) {
        Object lock=new Object();

        //创建消费者线程
        new Thread(new Runnable() {
            @Override
            public void run() {

                while (true) {
                    synchronized (lock) {
                        if (Resource.number >= 3) {
                            System.out.println("这有足够多的食物");
                            try {
                                lock.wait();//阻塞并释放锁
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        } else {
                            Resource.number++;//,一开时number=0,先++再打印
                            System.out.println("[p]:" + Resource.number);
                            lock.notify();//唤醒处于等待状态的线程,且不会释放锁
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }

            }
        }).start();
        Runnable task=new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (lock) {
                        if(Resource.number==0)
                        {
                            System.out.println("这没有足够的资源");
                            try {
                                lock.wait();//阻塞的同时会释放掉锁
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        else {
                            System.out.println("[c]"+Resource.number);//先打印,再--
                            Resource.number--;

                            lock.notify();//唤醒生产者线程,生产者如果没有处于等待,就没事
                            //只能唤醒别的线程
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }

                        }
                    }
                }
            }
        };
        new Thread(task).start();
    }

}

线程池:
如何获得线程池对象:


方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象 

计算密集型任务:核心线程数:cpu数+1

IO密集型任务:核心线程数:cpu数*2

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

参数一:  corePoolSize:指定线程池的核心线程的数量

参数二:maximumPoolSize:指定线程池的最大线程数量

参数三: long keepAliveTime:指定临时线程的存活时间(没有事情干)

参数四:unit:指定临时线程的存活时间单位(分,秒,天)

参数五:workQueue:指定线程池的任务队列

参数六:threadFactory:指定线程池的线程工厂

参数七: handler:指定线程池的任务拒接策略

例如:

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 8, TimeUnit.MINUTES,
                new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),//  // Executors.defaultThreadFactory()获取默认的线程池工厂
                new ThreadPoolExecutor.AbortPolicy());

临时线程什么时候创建:

新任务提交时发现核心线程都在忙,任务对列也满了,并且还可以创建临时线程

什么时候拒绝新任务:
核心线程和临时线程都满了,任务队列也满了 

一个任务类:

public class Task1 implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"输出yyyy");
        try{
        Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
public class test {
    public static void main(String[] args) {
        //创建一个线程池对象
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 5, 8, TimeUnit.MINUTES,
                new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),//  // Executors.defaultThreadFactory()获取默认的线程池工厂
                new ThreadPoolExecutor.AbortPolicy());

        //添加任务
        threadPoolExecutor.execute(new Task1());//线程池会自动创建一个线程,自动处理任务

        threadPoolExecutor.shutdown();//等待线程池所有任务执行完后关闭线程池
        threadPoolExecutor.shutdownNow();//立即关闭线程池
    }
}

方式二:使用Executors工具类

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定线程数量的线程池,如果某个线程因为异常关闭,那么线程池会创建出一个新的线程

public static ExecutorService newSingleThreadExecutor()

创建只有一个线程的线程池, 如果这个线程因为异常关闭,那么线程池会创建出一个新的线程

Callable任务:

 Interface Callable<V>

Callable支持结果返回,Runnable不行

Callable可以抛出异常,Runnable不行

Callable任务处理使用步骤:
1:创建线程池

2:定义Callable任务

3:创建Callable任务,提交任务给线程池

4:获取执行结果

public class test2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建线程池对象
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        //创建一个Callable类型的任务类

        Callable<Integer>callable=new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum=0;
                for(int i=0;i<10;i++)
                {
                    sum+=i;
                }
                return sum;
            }

        };
        //交给线程池处理(submit()方法),并获取返回值
        Future<Integer> submit = executorService.submit(callable);
        System.out.println(submit.get());//通过get方法获取返回值

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1591610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信创产品适配的前因后果

“信创”的本意是指“信息技术应用创新”。这个概念最早来源于“信创工委会”&#xff08;信息技术应用创新工作委员会&#xff09;&#xff0c;一个由24家专业从事软硬件关键技术研究及应用的国内单位&#xff0c;在2016年共同发起成立的非营利性社会组织。近些年来&#xff0…

GitHub repository - commits - branches - releases - contributors

GitHub repository - commits - branches - releases - contributors 1. commits2. branches3. releases4. contributorsReferences 1. commits 在这里可以查看当前分支的提交历史。左侧的数字表示提交数。 2. branches 可以查看仓库的分支列表。左侧的数字表示当前拥有的分…

android studio 网络请求okhttp3、okgo

一、在build.gradle文件里添加 implementation com.squareup.okhttp3:okhttp:4.9.0 implementation com.squareup.okhttp3:okhttp:3.12.0 implementation com.squareup.okio:okio:1.17.4 implementation com.lzy.net:okgo:3.0.4 implementation com.alibaba:fastjson:1.2.57 i…

25、链表-环形链表

思路&#xff1a; 这道题就是判断链表中是否有环&#xff0c;首先使用集合肯定可以快速地解决&#xff0c;比如通过一个set集合遍历&#xff0c;如果遍历过程中有节点在set中已经存在那么说明存在环。 第二种方式就是通过快慢指针方式寻找环。具体思路就是一个慢指针每次直走一…

Android适配平板屏幕尺寸

一、划分手机和平板 人为判断方法: 大于6英寸的就是平板。小于6英寸的都是手机 平板尺寸&#xff1a; 6英寸、7英寸、10英寸、14英寸… Android系统支持多配置资源文件&#xff0c;我们可以追加新的资源目录到你的Android项目中。命名规范&#xff1a; 资源名字-限制符 l…

2024年MathorCup数学建模B题甲骨文智能识别中原始拓片单字自动分割与识别研究解题文档与程序

2024年第十四届MathorCup高校数学建模挑战赛 B题 甲骨文智能识别中原始拓片单字自动分割与识别研究 原题再现&#xff1a; 甲骨文是我国目前已知的最早成熟的文字系统&#xff0c;它是一种刻在龟甲或兽骨上的古老文字。甲骨文具有极其重要的研究价值&#xff0c;不仅对中国文…

Go程序设计语言 学习笔记 第十一章 测试

1949年&#xff0c;EDSAC&#xff08;第一台存储程序计算机&#xff09;的开发者莫里斯威尔克斯在他的实验室楼梯上攀登时突然领悟到一件令人震惊的事情。在《一位计算机先驱的回忆录》中&#xff0c;他回忆道&#xff1a;“我突然完全意识到&#xff0c;我余生中的很大一部分时…

2024妈妈杯mathorcup数学建模C题 物流网络分拣中心货量预测及人员排班

一、数据预处理 数据清洗是指对数据进行清洗和整理&#xff0c;包括删除无效数据、缺失值填充、异常值检测和处理等。数据转换是指对数据进行转换和变换&#xff0c;包括数据缩放、数据归一化、数据标准化等。数据整理是指对数据进行整理和归纳&#xff0c;包括数据分组、数据聚…

一文读懂Java中的WebEndpointProperties类(附Demo)

目录 前言1. 基本知识2. Demo3. 彩蛋 前言 对于Java的相关知识&#xff0c;推荐阅读&#xff1a;java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; 1. 基本知识 Spring Boot 的配置类 WebEndpointProperties&#xff0c;用于配置 Web 端…

【python】基于pyttsx3库的字符串转音频文件

一、源码 import pyttsx3 engine pyttsx3.init() engine.setProperty(volume, 0.8) engine.setProperty(rate, 150) engine.save_to_file("Hello, World!", "output.mp3") engine.runAndWait()二、介绍 使用pyttsx3库&#xff0c;设置声音与速率&#x…

RTR3学习笔记

目录 引言第二章、图形渲染管线2.1 图形渲染管线架构概述&#xff08;1&#xff09;渲染管线的主要功能&#xff08;2&#xff09;渲染结果是由输入对象相互作用产生的&#xff08;3&#xff09;图像渲染管线的三个阶段&#xff08;4&#xff09;其他讨论 2.2 应用程序阶段&…

SpringBoo利用 MDC 机制过滤出单次请求相关的日志

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1.前言 2.MDC 是什么 3.代码实战 4.总结 1.前言 在服务出现故障时&#xff…

Composer 安装与配置

Composer 是 PHP 领域中非常重要的一个工具&#xff0c;它作为 PHP 的依赖管理工具&#xff0c;帮助开发者定义、管理、安装项目所依赖的外部库。Composer 的出现极大地简化了 PHP 项目的构建和管理过程&#xff0c;使得开发者可以更加专注于代码的编写和功能的实现。 Compose…

matlab使用教程(42)—常见的二维图像绘制方法

这个博客用于演示如何在 MATLAB 中创建曲线图、条形图、阶梯图、误差条形图、极坐标图、针状图、散点图。 1.曲线图 plot 函数用来创建 x 和 y 值的简单线图。 x 0:0.05:5; y sin(x.^2); figure plot(x,y) 运行结果&#xff1a; 线图可显示多组 x 和 y 数据。 x 0:0.05:…

气膜建筑的优势与应用—轻空间为您解答

气膜建筑作为一种利用气膜材料构建主体结构的建筑形式&#xff0c;在现代建筑领域日益受到关注。轻空间将介绍气膜建筑的优势以及其在不同领域的应用。 1. 轻便灵活&#xff1a; 气膜建筑采用轻质材料&#xff0c;相比传统建筑更为轻便&#xff0c;从而减轻了基础负荷和运输成本…

day05-Elasticsearch01

1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch 是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 例如&#xff1a; 在 GitHub 搜索代码在电商网站搜索商品在百度搜索答案在打…

Vue第三方组件使用

文章目录 一、组件传值二、elementui组件使用三、fontawesome图标 一、组件传值 1、父组件与孩子组件传值 在孩子组件中定义props属性&#xff0c;里面定义好用于接收父亲数据的变量。 孩子组件是Movie Movie.vue。注意看在Movie组件里面有props对象中的title和rating属性用…

如何利用python机器学习解决空间模拟与时间预测问题

徐老师&#xff1a;副教授&#xff1a;长期从事定量遥感、遥感数据同化、地表水热通量转化等相关领域的研究&#xff0c;发表多篇相关领域核心期刊论文&#xff0c;具有丰富的实践技术经验。 专题一、机器学习原理与概述 了解机器学习的发展历史、计算原理、基本定义&#xf…

ACL 2024 commit是否提交revision版本的论文

ACL 2024 commit是否提交revision版本的论文? 有大佬知道吗&#xff1f;&#xff01;&#xff01; 哎 ARR rebuttal阶段 让我们加实验&#xff0c;回复一时爽。。 现在又要提交pdf到ACL会议了&#xff0c;是提交之前的ARR版本的稿子&#xff0c;还是我承诺的 revision 稿啊&…

MySQL数据库max_allowed_packet参数

如上图所示的报错&#xff0c;我在提交接口的时候出现了这个错误&#xff1a; MySqlConnector.MySqlException:Error submitting 4MB packet;ensure max_allowed_packet is greater than 4MB.在MySQL数据库中&#xff0c;有一个参数叫max_allowed_packet&#xff0c;这个参数会…