package demo;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
public class ThreadOrder {
static class TaskProcess implements Runnable {
private Queue<Runnable> tasks;//获取任务的队列
private Object myLock;//本线程等待的锁
private Object nextLock;//通知下个线程的锁
private CountDownLatch latch;//通知主线程:本线程已经就绪
public TaskProcess(Queue<Runnable> tasks, Object myLock, Object nextLock, CountDownLatch latch) {
this.tasks = tasks;
this.myLock = myLock;
this.nextLock = nextLock;
this.latch = latch;
}
public void run() {
String name = Thread.currentThread().getName();//当前线程的名字
synchronized (myLock) { //拿到自己的锁后
latch.countDown();//拿到自己的锁后,通知主线程:本线程已经就绪
Runnable task;//要执行的任务
while (true) {
// 1.等待被通知执行
try {
myLock.wait();
} catch (InterruptedException e) {
System.out.println("运行异常:" + name);
notifyNextThread();//必需 通知下个线程,以防止下一个线程永久等待
return;
}
// 2.被通知后,开始获取任务并执行
task = tasks.poll();
if (task == null) {//没有任务
System.out.println("没有任务,线程退出:" + name);
notifyNextThread();//必需 通知下个线程,以防止下一个线程永久等待
return;
}
// 3.执行任务过程
task.run();
// 4.通知下一个线程执行任务
notifyNextThread();
}
}
}
private void notifyNextThread() {
synchronized (nextLock) {
nextLock.notify();
}
}
}
public static void main(String[] args) throws InterruptedException {
// 1. 定义任务队列
final Queue<Runnable> tasks = new LinkedList<Runnable>();
for (int i = 0; i < 100; i++) {
final int finalI = i;
tasks.offer(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " 执行任务:" + finalI);
}
});
}
// 2.定义执行任务的线程数(按次序执行)
// int number = 2;//TODO 修改这里可以 改变 执行任务的线程序列个数
int number = 10;//TODO 修改这里可以 改变 执行任务的线程序列个数
// 定义所有线程就绪通知机制
CountDownLatch latch = new CountDownLatch(number);
// 定义线程顺序执行用以交互的锁
Object[] locks = new Object[number];
for (int i = 0; i < number; i++) {
locks[i] = new Object();
}
for (int i = 0; i < number; i++) {
Object myLock = locks[i];
Object nextLock = locks[i < number - 1 ? i + 1 : 0];
Thread t = new Thread(new TaskProcess(tasks, myLock, nextLock, latch) {
}, "Thread-" + i);
t.start();
}
//等待所有线程就绪
latch.await();
//获取到第一个要执行的线程的锁,予以激活
Object firstLock = locks[0];
// 激活线程序列进行处理
synchronized (firstLock) {
firstLock.notify();// 激活线程序列进行处理
}
}
}
相关推荐
java实现的任务队列
NULL 博文链接:https://noddle0592.iteye.com/blog/2185620
java多线程实现任务组中的子任务按顺序执行
线程的调用是随机的,但是有个需求是在线程池中开辟多个线程按顺序去执行一组任务,比如说一个任务组下面有多个子任务,需要按子任务的顺序依次提交 代码: public class TestThread { public static void main(String[] args) { //创建线程池 ThreadPoolExecutor executorService = new ThreadPoolExecutor(10, 10, 0L
利用Android系统漏洞实现后台弹窗(外弹)
关键:从 Android 8.0(API 26)开始,禁止使用 context.sendBroadcast() 发送隐式广播(即没有指定 setPackage() 或明确组件的广播)。demo核心代码展示利用Android显示系统和广播系统的漏洞实现在后台弹窗的功能,支持最新Android15,16版本。核心功能都是在so层去做,大量使用了jni反调, 如果要上架到应用市场,需要对代码做进一步混淆,加固以应对市场安全扫描。3,开启虚拟显示窗口,这是个透明像素窗口。5,可开启一个线程,调用这个外弹窗口。
多线程顺序执行的几种写法
前言 这是一道常见面试题,我也碰到过,下面介绍的这几种写法也是对并发编程常用工具掌握程度的一个考察,是一道很好的面试题。一共有以下几种写法,下面来分别介绍。 join写法(两种写法) 线程池写法 wait、notify写法 Condition写法 CountDownLatch写法 CyclicBarrier写法 Thread.sleep写法 CompletableFuture写法 join写法 join()方法的作用,把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。 也就是说,
GX Works2系统启动失败排查指南:从环境配置到修复方案
在工业自动化与PLC编程调试中,软件启动异常是常见的工程痛点。当开发工具因系统环境配置不当而频繁报错时,往往不是简单的重启能解决的。运行库缺失、区域设置错误、临时目录失效或系统服务被禁用,都可能导致编程软件无法完成初始化流程。掌握从基础环境检查到系统组件修复的系统性排查思路,是提升工控开发效率的关键能力。本文从软件初始化原理出发,结合Windows系统维护实践,梳理一套适用于工业软件启动故障的通用诊断方法,并自然聚焦到三菱GX Works2常见启动失败问题的实际处理,帮助工程师快速定位并解决环境性故障,保障
全球第一开源云ERP Odoo操作手册 模块安装和界面汉化指南
Odoo 的功能包含在不同的模块中, 刚创建的数据库除 Odoo 的核心模块外, 其它模块并没有被安装到系统中,你可以根据需要安装它们。本节将介绍安装模块和界面汉化的相关知识。
多线程顺序运行的 4 种方法
举例:在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后,线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。// 下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序。简单说一下子线程与主线程的区别,子线程指的是发生在Thread内部的代码,主线程指的是发生在main函数中的代码。我们可以在main函数中通过。
STM32cube HAL库两条命令实现i2c通信---Nucleo L476RG用I2C实现tmp117模块温度读取并串口打印
Getting Started with STM32 - I2C Example
java多线程保证顺序执行
多线程保证顺序执行
Dify 从入门到精通:第一篇 - 基础介绍与快速上手
Dify是一个开源的低代码平台,旨在简化大型语言模型(LLM)应用的开发流程。本文作为"Dify从入门到精通"系列的首篇,全面介绍了Dify的核心概念、安装步骤和基本使用方法。文章首先解析了Dify的多模型支持、低代码开发等特点,然后详细讲解了基于Docker的安装配置过程,包括系统要求、环境变量设置等。通过创建一个邮件助手应用的实际示例,展示了Dify的可视化工作流设计功能。最后简要介绍了高级特性和最佳实践,为后续深入学习奠定基础。本文为开发者提供了从零开始使用Dify构建AI应用的完
Unity动态创建Avatar骨骼映射
Unity Avatar骨骼映射动态创建,适配Unity通用动画,无需经过第三方建模软件,可运行时创建
Java中控制多线程顺序执行
Java的线程调度策略是基于线程优先级的抢占式调度,同优先级的线程的执行顺序是看JVM心情的、不可预测的。那有什么办法来控制多线程按照开发者意愿的顺序执行呢?
103:vue+cesium 设置球体水部分颜色为黄色
本示例在 Vue + cesium 项目中设置球体水部分颜色为黄色。这里的操作是将球体内部设置为空的,在地球内部添加一个黄色的圆球,这样水的部分就被突出出来了。直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果.
[jS 事件循环理解] 主线程 宏任务 微任务 - 执行顺序优先级理解
最近看了一个帖子把js单线程中 , 主线程 | 宏任务 | 微任务 的调用顺序讲解的很直白精巧 , 记录一下以供查阅1.主线程, 可以理解为从上到下顺序执行的一个js线程2. 宏任务 script / setTimeOut /setInterval等3. 微任务主要有promise等4. 热知识: new Promise 也算主线程执行的顺序 我们可以这样理解1.主线程内顺序执行2.遇到 setTimeout等宏任务, 会把宏任务的回调代码放到宏任务队列中排队。
Qt Android MySql 数据库驱动编译(详细图解步骤)
第一步.先介绍下环境搭建: Qt 版本 5.12.11 下载链接 https://download.qt.io/archive/qt/5.12/5.12.11/qt-opensource-linux-x64-5.12.11.run Ubuntu 18.04.6 LTS 下载链接 JDK版本 1.8.0_191 下载链接https://www.oracle.com/java/technologies/downloads/ Android Studio版本 ...
霍尼韦尔SoftMaster使用说明
霍尼韦尔SoftMaster使用说明
js宏观任务、微观任务
困了 睡觉
Outlook Express 6 (OE6) for Win7/Win8/Win10
英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。
JS执行机制与事件循环
3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。在做一件事情的时候,因为这件事情会浪费很长时间,在做这件事的同时,你还可以去处理其他事情。由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环。前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。立即执行的任务,同步任务都是再主线程上执行的,形成一个执行栈。1、先执行执行栈中的同步任务;
visio安装包
Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。
Javascript同步与异步
Javascript同步与异步 JS是单线程 JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为Javascript这门脚本语言诞生的使命所致——JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先进行添加,之后再删除。 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个务。这样所导致的问题是∶如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
关于Event Loop机制的解析
关于Event Loop机制的解析
WIN32多线程程序设计-读书笔记
持续更新~ 线程相比进程的优点是线程廉价,表现在:线程启动比较快,退出比较快,对系统资源的冲击比较小,而且,线程彼此分享了大部分核心对象的拥有权 从WIN32的角度看,进程含有内存(代码区、数据区、堆栈)和资源(对象、dll模块、线程,file handle) 多线程通信时需要把这个进程的handle明明白白的拷贝一份给另一个进程使用,而线程不需要,线程和handle生活在同一个进程之中 ...
cartographer 线程池+队列
C++简单线程池1.线程池1.1 线程池定义1.2 为何使用线程池1.3 线程池的工作原理1.5 工作者线程&I/O线程 1.线程池 1.1 线程池定义 简单来说就是有一堆已经创建好的线程(最大数目一定),初始化时他们都处于空闲状态,当有新的任务进来时,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他的任务使用,当线程池中的线程都在处理任务...
线程池是如何重复利用空闲的线程来执行任务的?
作者:跑步_跑步blog.youkuaiyun.com/anhenzhufeng/article/details/88870374在Java开发中,经常需要创建线程去执行一些任务,实现起来也非常方便,...
JS执行队列
JS执行队列 JS 一大特点就是 单线程,即同一时间只能做一件事 单线程就意味着所有的任务需要排队,前一个任务结束后才会执行下一个任务。 这样可能造成的结果是:如果JS执行的时间过长,会导致页面的渲染不连贯,导致页面渲染加载阻塞的感觉 为了解决这个问题,JS出现了同步和异步 同步:前一个任务结束后才会执行下一个任务 异步:在处理一个任务的同时还可以执行其他任务 区别:在流水线上各个流程的执行顺序不同 console.log(1); window.setTimeout(function () { con
封装一个阻塞队列,轻松实现排队执行任务功能!
前言 个人觉得队列的使用在项目开发中挺多地方可以用到的,所以将如何封装一个队列的过程记录下来,总体来说难度并不大,但毕竟能力有限,如果各位有好的建议或意见欢迎提出来,如果本文能帮到你的话,记得点赞哦。 需求背景 在项目开发中,会经常遇到一些需要排队执行的功能,比如发动态时上传多张图片,需要一张一张的上传,比如直播间动画连需发送或者收到消息需要展示时,需要一个一个动画去展示等等场景,这时候会容易想到用队列去实现,但是我想不少小伙伴会直接弄一个 list,存着要执行的任务,然后通过递归的方式去遍历列表实现
JS 执行队列
JS 的一大特点就是单线程,也就是说,同一时间只能做一件事,这是因为 JS这门语言诞生的使命导致的—— JS 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。应该先添加,然后再删除。 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 同步和异步 为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出
js执行队列
1.1 js是单线程 js语言的一大特点就是单线程,也就是说,同一时间只能做一件事,这是因为js 这门脚本语言诞生的使命导致–js是为处理页面中用户的交互,以及操作DOM而诞生的。 比如我们对某个DOM元素进行添加和删除操作,不能同时进行,应该先进行添加,之后再删除 1.2 同步和异步 为了解决这个问题,利用多核CPU的计算能力,HTML5提出Wep Worker标准,允许js脚本创建多个线程,于是js中出现了同步和异步 (1)同步 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的,
910



被折叠的 条评论
为什么被折叠?



