场景

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

问题

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

解决方法

在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. 几个有趣的WEB设备API(二)

    浏览器和设备之间还有很多有趣的接口, 1.屏幕朝向接口 浏览器有两种方法来监听屏幕朝向,看是横屏还是竖屏. (1)使用css媒体查询的方法 /* 竖屏 */ @media screen and (or ...

  2. mybatis plugins实现项目【全局】读写分离

    在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离 注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html ...

  3. C#中如何调整图像大小

    在本篇文章中,我将介绍如何在C#中来调整你想要的图像大小.要实现这一目标,我们可以采取以下几个步骤: 1.首先要获取你想要调整大小的图像: string path = Server.MapPath(& ...

  4. 记录一次bug解决过程:数据迁移

    一 总结 不擅长语言表达,勤于沟通,多锻炼 调试MyBatis中SQL语法:foreach 问题:缺少关键字VALUES.很遗憾:它的错误报的让人找不着北. 二 BUG描述:MyBatis中批量插入数 ...

  5. JavaScript中String对象的方法介绍

    1.字符方法 1.1 charAt() 方法,返回字符串中指定位置的字符. var question = "Do you like JavaScript?"; alert(ques ...

  6. 【干货分享】流程DEMO-请休假

    流程名: 请假申请  流程相关文件: 流程包.xml WebService业务服务.xml WebService.asmx WebService.cs  流程说明: 流程中集成了webservice服 ...

  7. 安卓客户端a标签长按弹框提示解决办法

    昨天工作时候发现一个bug,是关于a标签的,在安卓客户端中,如果是a标签的话,长按会出现一个弹框,如图所示 是因为安卓客户端的长按触发机制,以后进行wap端开发的时候,如果用到跳转页面尽量不要用a标签 ...

  8. Android中实现APP文本内容的分享发送与接收方法简述

    谨记(指定选择器Intent.createChooser()) 开始今天的内容前,先闲聊一下: (1)突然有一天头脑风暴,对很多问题有了新的看法和见解,迫不及待的想要分享给大家,文档已经写好了,我需要 ...

  9. PC虚拟现实应用的性能分析与优化:从CPU角度切入

    如今,虚拟现实 (VR) 技术正日益受到欢迎,这主要得益于遵循摩尔定律的技术进步让这一全新体验在技术上成为可能.尽管虚拟现实能给用户带来身临其境般的超凡体验,但相比传统应用,其具有双目渲染.低延迟.高 ...

  10. 学习笔记 :DrawText

    最近在做一个TStringGrid的自绘处理,在画文字处理上遇到了高度的计算问题.后来经过一段时间还是找到了一些方法: 1.使用TLabel 这个方法是有点绕路的,方法倒是简单,就是使用AutoSiz ...