场景

开发中遇到一个场景,业务操作会不定时的产生工作任务,这些工作任务需要放入到一个队列中,而另外会有一个线程一直检测这个队列,队列中有任务就从队列中取出并进行运算。

问题

业务场景倒是简单,只不过这里会有一个问题,就是如果队列中没有数据那么线程就会一直扫描,这样就会浪费资源。

解决方法

在windows中有一个事件对象可以用于线程的控制,Event有两种状态:有信号和无信号,通过这个信号来做一个开关,可以达到线程的开关。在.net中有个AutoResetEvent类是实现这套方法的,但在java中我没有找到类似的实现,但是java并发包中有个Semaphore,那就通过这个Semaphore来完成吧。

怎么做

Semaphore可以设置信号量的数量,每一个信号量称为一个许可证,需要进行同步的线程向这个信号量对象获取许可证,获得成功则线程继续执行,如果没有许可证则会阻塞。我们这个场景下只要将信号量设置为1个许可证,然后通过控制这个许可证即可实现Event的效果。

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore; public class ThreadRunable {
private static ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
private static Semaphore semp = new Semaphore(1); public static void main(String[] args) throws InterruptedException {
semp.acquire();//先占用信号量 Thread newThread = new Thread(new Worker());
newThread.start(); try {
Thread.sleep(1000);
queue.add("第1条数据");
semp.release();//放入数据放释放信号量,使得线程可以运行
System.out.println("可用许可证:" + semp.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(5000);
queue.add("第2条数据");
semp.release();//放入数据放释放信号量,使得线程可以运行
System.out.println("可用许可证:" + semp.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
} static class Worker implements Runnable { @Override
public void run() {
while (true) {
try {
semp.acquire();//获取许可证,如果没有可用许可证则阻塞 //业务代码,从队列中读数据做一些想干的事情
while (queue.isEmpty() == false) {
String value = queue.poll();
if (value != null && value != "") {
System.out.println("value: " + value);
}
} System.out.println("it's down.");
} catch (Exception e) {
}
}
} }
}

在段代码就是一个简单的模拟,实现的过程如下:

1、全局初始化信号量对象,设置一个许可证

2、首先占用许可证,使得线程在获取许可证时就会阻塞

3、然后模拟一些添加队列的数据,在添加队列的时候同时释放许可证,这样就可以唤醒线程了

4、线程唤醒后去读取队列并做一些操作,完成后又去尝试获取许可证

5、如果没有许可证则阻塞,直到下次有数据添加队列时再次释放许可证时再次唤醒线程

最后运行的结果:

可用许可证:1
value: 第1条数据
it's down.
可用许可证:1
value: 第2条数据
it's down.

Java模拟Windows的Event的更多相关文章

  1. Jsoup实现java模拟登陆

    Jsoup实现java模拟登陆 2013-10-29 14:52:05|  分类: web开发|举报|字号 订阅     下载LOFTER我的照片书  |     1:如何获取cookies. 1.1 ...

  2. [Java] 模拟HTTP的Get和Post请求

    在之前,写了篇Java模拟HTTP的Get和Post请求的文章,这篇文章起源与和一个朋友砍飞信诈骗网站的问题,于是动用了Apache的comments-net包,也实现了get和post的http请求 ...

  3. java模拟浏览器包selenium整合了htmlunit,火狐浏览器,IE浏览器,opare浏览器驱

    //如果网页源码中有些内容是js渲染过来的,那你通过HttpClient直接取肯定取不到,但是这些数据一般都是通过异步请求传过来的(一般都是通过ajax的get或者post方式).那么你可以通过火狐浏 ...

  4. 上curl java 模拟http请求

    最近,我的项目要求java模拟http请求,获得dns解决 tcp处理过的信息特定的连接. java api提供urlConnection apache提供的httpClient都不能胜任该需求,二次 ...

  5. 使用Java模拟一个简单的Dos学生成绩管理系统:

    使用Java模拟学生成绩管理系统... ------------------- 学生成绩管理系统:需要实现的功能:1.录入学生的姓名和成绩2.显示列表.列表中包括学生姓名与成绩3.显示最高分.最低分的 ...

  6. 浏览器与服务器交互原理以及用java模拟浏览器操作v

    浏览器应用服务器JavaPHPApache * 1,在HTTP的WEB应用中, 应用客户端和服务器之间的状态是通过Session来维持的, 而Session的本质就是Cookie, * 简单的讲,当浏 ...

  7. java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例

    java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例HttpClient 测试类,提供get post方法实例 package com.zdz.httpclient; i ...

  8. Window对应的类为java.awt.Windows, 它可独立于其他Container而存在

    Window对应的类为java.awt.Windows, 它可独立于其他Container而存在,它有两个子类, Frame和Dialog, Frame是具有标题(title)和可伸缩的角(resiz ...

  9. java模拟http的get和post请求

    如题,使用Java模拟GET和POST请求.使用GET可以实现网页抓取,使用POST可以实现对某些网站登录的暴力破解.不过仅是练习,实际意义不大. import java.io.IOException ...

随机推荐

  1. 谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  2. 关于自己写C++的一点风格

    现在,我学了很长时间的C++,但是自己就是无法精通.许多知识是入门书上没有的.现在写C++最重要的就是风格问题. 我现在的C++风格: 把自己所有的东西都放在一个名称空间下. 没有全局的函数,有的函数 ...

  3. [BOT] 一种android中实现“圆角矩形”的方法

    内容简介 文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式,四个角可以分别指定为圆角.思路是利用"Xfermode + Path"来进行 ...

  4. 千呼万唤始出来,微软Power BI简体中文版官网终于上线了,中文文档也全了。。

    前几个月时间,研究微软Power BI技术,由于没有任何文档和资料,只能在英文官网瞎折腾,同时也发布了英文文档的相关文章:系列文章,刚好上周把文章发布完,结果简体中文版上线了.哈哈,心里有苦啊,早知道 ...

  5. 玩转spring boot——结合redis

    一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...

  6. The Zen of Python

    Beautiful is better than ugly. 优美总比丑陋好Explicit is better than implicit. 直率总比含蓄好Simple is better than ...

  7. git添加GitHub远程库

    已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作 首先,登陆GitHub, ...

  8. mysql开启慢查询日志及查询--windows

    MySQL慢查询配置 1. 慢查询有什么用? 它能记录下所有执行超过long_query_time时间的SQL语句, 帮你找到执行慢的SQL, 方便我们对这些SQL进行优化. 2. 如何开启慢查询? ...

  9. 数据库备份并分离日志表(按月)sh 脚本

    #!/bin/sh year=`date +%Y` month=`date +%m` day=`date +%d` hour=`date +%H` dir="/data/dbbackup/f ...

  10. 为Xamarin更好的开发而改写的库

    欢迎大家加入以下开源社区 Xamarin-Cn:https://github.com/Xamarin-Cn Mvvmcross-Cn:https://github.com/Mvvmcross-Cn  ...