自己写的关于生产者与消费者模式,还有定时任务的demo
为了加深对生产者消费者模式的理解,特意写了这个demo,里面还包含了一个自己写的定时任务。代码下载地址:http://download.csdn.net/detail/li_yan_fei/9811572
是个maven项目,只用了spring框架。
学到的内容有3个
第一:加深了对生产者消费者模式的理解
第二:java Object 的wait() timeout数值如果等于0,则会造成线程一直等待下去,除非被notify唤醒
第三:java中main函数主线程死掉不会影响其他线程的正常执行(除了守护线程)。因为main函数主线程和其他非守护线程是一样的。
代码:
1.一个实现了按时间排序的队列
-
package com.lyf.task;
-
-
import java.lang.reflect.InvocationTargetException;
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import org.apache.commons.beanutils.BeanUtils;
-
-
import com.lyf.bean.TaskInfo;
-
-
/**
-
* @ClassName: TaskStack
-
* @Description: 实现了一个按照时间顺序排列的队列
-
* @author yanfei.li
-
* @date 2017年4月10日 下午1:53:49
-
* @Company:
-
*/
-
public class TaskStack {
-
-
private List<TaskInfo> queue = new ArrayList<TaskInfo>();
-
-
public TaskStack() {
-
}
-
-
/**
-
* 功能描述: 往队列里塞任务
-
* @Title: push
-
* @author yanfei.li
-
* @date 2017年4月11日 上午11:41:50
-
* @param taskInfo
-
* @return void
-
* @throws
-
*/
-
public synchronized void push(TaskInfo taskInfo) {
-
-
// 如果是空队列,直接将任务放进去就可以了
-
if (this.queue.isEmpty()) {
-
this.queue.add(taskInfo);
-
// 唤醒正在调用pop的消费者线程
-
this.notify();
-
return;
-
}
-
// 如果队列不是空的,就要比较执行时间了,根据执行时间排序
-
for (int index = 0; index < this.queue.size(); index++) {
-
TaskInfo info = this.queue.get(index);
-
if (info.getRunTime() > taskInfo.getRunTime()) {
-
this.queue.add(index, info);
-
this.notify();
-
return;
-
}
-
}
-
}
-
-
/**
-
* 功能描述: 从队列里取任务
-
* @Title: pop
-
* @author yanfei.li
-
* @date 2017年4月11日 上午11:41:28
-
* @return TaskInfo
-
* @throws
-
*/
-
public synchronized TaskInfo pop() {
-
-
// 如果队列里没有,就释放锁,等待唤醒
-
if (this.queue.isEmpty()) {
-
try {
-
this.wait();
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
-
while (true) {
-
TaskInfo taskInfo = this.queue.get(0);
-
Long now = System.currentTimeMillis();
-
if (now >= taskInfo.getRunTime()) {// 如果取出的任务到了执行的时间了,就返回该任务并且从队列中移除此任务。这里一定要注意了 判断条件一定要有=号,因为很可能出现相等的情况,如果进入了else中,就会造成wait(0).如果没有notify就一直等下去了
-
this.queue.remove(0);
-
return taskInfo;
-
} else {
-
try {
-
System.out.println("pop--------" + (taskInfo.getRunTime() - now));
-
this.wait(taskInfo.getRunTime() - now);
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
}
-
-
/**
-
* 功能描述: 从队列里移除任务
-
* @Title: remove
-
* @author yanfei.li
-
* @date 2017年4月11日 上午11:41:06
-
* @param taskInfo
-
* @return void
-
* @throws
-
*/
-
public synchronized void remove(TaskInfo taskInfo) {
-
this.queue.remove(taskInfo);
-
}
-
-
/**
-
* 功能描述: 返回队列里所有的任务
-
* @Title: getAll
-
* @author yanfei.li
-
* @date 2017年4月11日 上午11:40:36
-
* @return List<TaskInfo>
-
* @throws
-
*/
-
public synchronized List<TaskInfo> getAll() {
-
List<TaskInfo> retList = new ArrayList<TaskInfo>();
-
for (TaskInfo taskInfo : this.queue) {
-
try {
-
TaskInfo retTask = new TaskInfo();
-
BeanUtils.copyProperties(retTask, taskInfo);
-
retList.add(retTask);
-
} catch (IllegalAccessException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} catch (InvocationTargetException e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
-
}
-
return retList;
-
}
-
}
2.消费者
-
package com.lyf.task;
-
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
-
import com.lyf.bean.TaskInfo;
-
import com.lyf.util.SpringContextUtils;
-
-
/**
-
* @ClassName: TaskExecutor
-
* @Description: 任务执行器,相当于消费者
-
* @author yanfei.li
-
* @date 2017年4月10日 下午1:52:00
-
* @Company:
-
*
-
*/
-
public class TaskExecutor implements Runnable {
-
-
private TaskStack taskStack = null;//任务队列
-
private ExecutorService fixedThreadPool = null;//线程执行池,选择的固定线程池大小,由sping初始化
-
-
public TaskExecutor(TaskStack taskStack,int poolSize) {
-
this.taskStack = taskStack;
-
this.fixedThreadPool = Executors.newFixedThreadPool(poolSize);
-
}
-
-
public void run() {
-
-
while(true){
-
try {
-
//获取当前要执行的任务
-
TaskInfo taskInfo = taskStack.pop();
-
//解析taskinfo信息,获取真正执行的task
-
TaskInterface instance = (TaskInterface)SpringContextUtils.getBean(taskInfo.getApi());
-
//将任务信息,传递给将要执行的task
-
instance.setTaskInfo(taskInfo);
-
//将任务放到线程池中执行
-
this.fixedThreadPool.submit(instance);
-
//如果是周期性的任务,则计算出下次执行时间,然后放到队列中
-
if(instance.hasNext()){
-
this.taskStack.push(instance.next());
-
}
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
-
}
-
-
}
3.任务bean
-
package com.lyf.bean;
-
-
import java.io.Serializable;
-
-
/**
-
* @ClassName: TaskInfo
-
* @Description: 任务实体
-
* @author yanfei.li
-
* @date 2017年4月10日 下午1:54:58
-
* @Company:
-
*
-
*/
-
public class TaskInfo implements Serializable {
-
-
private static final long serialVersionUID = 8609311967819063807L;
-
-
private String id;// 任务id
-
-
private String type;// 任务类型
-
-
private String runAt;// 执行时间规则
-
-
private String cron;// cron表达式
-
-
private long runTime;// 执行时间
-
-
private String api;// 执行接口
-
-
private Object[] params;// 任务参数
-
-
public String getId() {
-
return id;
-
}
-
-
public void setId(String id) {
-
this.id = id;
-
}
-
-
public String getType() {
-
return type;
-
}
-
-
public void setType(String type) {
-
this.type = type;
-
}
-
-
public String getRunAt() {
-
return runAt;
-
}
-
-
public void setRunAt(String runAt) {
-
this.runAt = runAt;
-
}
-
-
public String getCron() {
-
return cron;
-
}
-
-
public void setCron(String cron) {
-
this.cron = cron;
-
}
-
-
public long getRunTime() {
-
return runTime;
-
}
-
-
public void setRunTime(long runTime) {
-
this.runTime = runTime;
-
}
-
-
public String getApi() {
-
return api;
-
}
-
-
public void setApi(String api) {
-
this.api = api;
-
}
-
-
public Object[] getParams() {
-
return params;
-
}
-
-
public void setParams(Object[] params) {
-
this.params = params;
-
}
-
-
}
4.任务接口
-
package com.lyf.task;
-
-
import com.lyf.bean.TaskInfo;
-
-
/**
-
* @ClassName: TaskInterface
-
* @Description: TODO
-
* @author yanfei.li
-
* @date 2017年4月11日 下午12:00:10
-
* @Company:
-
*
-
*/
-
public interface TaskInterface extends Runnable {
-
-
/**
-
* 功能描述: 设置任务
-
* @Title: setTaskInfo
-
* @author yanfei.li
-
* @date 2017年4月11日 下午12:03:28
-
* @param taskInfo
-
* @return void
-
* @throws
-
*/
-
public void setTaskInfo(TaskInfo taskInfo);
-
/**
-
* 功能描述: 判断此任务是否还需要执行,针对的是循环性的任务
-
* @Title: hasNext
-
* @author yanfei.li
-
* @date 2017年4月11日 下午12:02:14
-
* @return boolean
-
* @throws
-
*/
-
public boolean hasNext();
-
/**
-
* 功能描述: 返回下次要执行的任务
-
* @Title: next
-
* @author yanfei.li
-
* @date 2017年4月11日 下午12:02:18
-
* @return TaskInfo
-
* @throws
-
*/
-
public TaskInfo next();
-
}
5.实现了任务接口的任务抽象模板类
-
package com.lyf.task;
-
-
import com.lyf.bean.TaskInfo;
-
import com.lyf.util.SpringCronResolveUtil;
-
-
/**
-
* @ClassName: TaskInstance
-
* @Description: 任务执行的模板类
-
* @author yanfei.li
-
* @date 2017年4月11日 下午2:47:57
-
* @Company:
-
*
-
*/
-
public abstract class TaskInstance implements TaskInterface {
-
-
protected TaskInfo taskInfo;
-
-
-
public void run() {
-
-
try {
-
this.before();
-
this.execute();
-
this.after();
-
} catch (Exception e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
} finally {
-
//如果要记录日志什么的,可以放到这里
-
}
-
-
}
-
-
/**
-
* 功能描述: 任务执行前执行的方法,比如做一些初始化工作
-
* @Title: before
-
* @author yanfei.li
-
* @date 2017年4月11日 下午2:50:43
-
* @return void
-
* @throws
-
*/
-
protected abstract void before() throws Exception;
-
-
/**
-
* 功能描述: 任务执行的具体方法
-
* @Title: excute
-
* @author yanfei.li
-
* @date 2017年4月11日 下午2:51:25
-
* @return void
-
* @throws
-
*/
-
protected abstract void execute() throws Exception;
-
-
/**
-
* 功能描述: 任务执行完后执行的方法
-
* @Title: after
-
* @author yanfei.li
-
* @date 2017年4月11日 下午2:51:41
-
* @return void
-
* @throws
-
*/
-
protected abstract void after() throws Exception;
-
-
-
public void setTaskInfo(TaskInfo taskInfo) {
-
this.taskInfo = taskInfo;
-
}
-
-
public boolean hasNext() {
-
if (this.taskInfo != null && !this.taskInfo.getRunAt().equals("now")) {
-
return true;
-
}
-
return false;
-
}
-
-
public TaskInfo next() {
-
if (this.taskInfo != null) {
-
this.taskInfo.setRunTime(
-
SpringCronResolveUtil.nextExecutionTime(this.taskInfo.getCron(), this.taskInfo.getRunTime()));
-
System.out.println("next===========" + (taskInfo.getRunTime() - System.currentTimeMillis()));
-
return this.taskInfo;
-
}
-
return null;
-
}
-
-
}
6.具体任务实现类
-
package com.lyf.task;
-
-
import org.springframework.context.annotation.Scope;
-
import org.springframework.stereotype.Service;
-
-
@Service("MyTask")
-
@Scope("prototype")
-
public class MyTask extends TaskInstance {
-
-
@Override
-
protected void before() throws Exception {
-
System.out.println("MyTask--------------before-------------");
-
-
}
-
-
@Override
-
protected void execute() throws Exception {
-
System.out.println("MyTask--------------execute-------------");
-
-
}
-
-
@Override
-
protected void after() throws Exception {
-
System.out.println("MyTask--------------after-------------");
-
}
-
-
}
7.任务service
-
package com.lyf.task;
-
-
import com.lyf.bean.TaskInfo;
-
-
public interface TaskService {
-
-
public void startTask(TaskInfo task);
-
}
8.实现类
-
package com.lyf.task;
-
-
import com.lyf.bean.TaskInfo;
-
import com.lyf.util.SpringCronResolveUtil;
-
-
public class TaskServiceImpl implements TaskService{
-
-
private TaskStack taskStack = null;
-
private TaskExecutor executor = null;
-
-
public TaskServiceImpl(Integer poolSize) {
-
this.taskStack = new TaskStack();
-
if(poolSize != null){
-
executor = new TaskExecutor(this.taskStack, poolSize);
-
new Thread(executor).start();
-
}
-
this.init();
-
}
-
-
private void init(){
-
//做一些其他的初始化工作
-
}
-
-
public void startTask(TaskInfo task) {
-
-
if (task == null) {
-
return;
-
}
-
-
//首次执行,设置runTime
-
if (task.getRunAt().equals("now")) {
-
task.setRunTime(System.currentTimeMillis() - 1);
-
} else {
-
if (task.getCron() == null || "".equals(task.getCron().trim())) {
-
return;
-
}
-
task.setRunTime(SpringCronResolveUtil.nextExecutionTime(task.getCron()));
-
}
-
this.taskStack.push(task);
-
}
-
-
}
9.从spring容器中获取bean的工具类(在多线程环境下使用spring注解无法注入bean,所以需要手动获取bean)
-
package com.lyf.util;
-
-
import org.springframework.beans.BeansException;
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.ApplicationContextAware;
-
-
public class SpringContextUtils implements ApplicationContextAware {
-
-
private static ApplicationContext applicationContext = null;
-
/**
-
* 当继承了ApplicationContextAware类之后,那么程序在调用
-
* getBean(String)的时候会自动调用该方法,不用自己操作
-
*/
-
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-
SpringContextUtils.applicationContext = applicationContext;
-
}
-
-
public static ApplicationContext getApplicationContext(){
-
return SpringContextUtils.applicationContext;
-
}
-
/**
-
* 功能描述: 根据name从spring容器中返回bean
-
* @Title: getBean
-
* @author yanfei.li
-
* @date 2017年4月11日 下午1:47:17
-
* @param name
-
* @throws BeansException
-
* @return Object
-
*/
-
public static Object getBean(String name)throws BeansException{
-
return applicationContext.getBean(name);
-
}
-
/**
-
* 功能描述: 根据name和类型从spring容器中返回bean
-
* @Title: getBean
-
* @author yanfei.li
-
* @date 2017年4月11日 下午1:46:46
-
* @param name
-
* @param requireType
-
* @throws BeansException
-
* @return Object
-
*/
-
public static <T> Object getBean(String name,Class<T> requireType)throws BeansException{
-
return applicationContext.getBean(name,requireType);
-
}
-
-
}
10.解析cron表达式的util(表达式只能是以空格分割的包含6个字符的字符串,不然会报错)
-
package com.lyf.util;
-
-
import java.util.Date;
-
-
import org.springframework.scheduling.support.CronSequenceGenerator;
-
-
/**
-
* @ClassName: SpringCronResolveUtil
-
* @Description: 解析cron字符串的工具类
-
* @author yanfei.li
-
* @date 2017年4月11日 下午2:59:44
-
* @Company:
-
*
-
*/
-
public class SpringCronResolveUtil {
-
-
/**
-
* 功能描述: 根据当前时间计算并返回下次执行时间
-
* @Title: nextExecutionTime
-
* @author yanfei.li
-
* @date 2017年4月11日 下午3:00:56
-
* @param cron 表达式字符串,包含6个以空格分开的字符
-
* @return long
-
* @throws
-
*/
-
public static long nextExecutionTime(String cron){
-
CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cron);
-
Date lastTime = new Date();
-
Date nexDate = cronSequenceGenerator.next(lastTime);
-
-
return nexDate.getTime();
-
-
}
-
-
/**
-
* 功能描述: 根据最后一次执行时间计算并返回下次执行时间
-
* @Title: nextExecutionTime
-
* @author yanfei.li
-
* @date 2017年4月11日 下午3:00:23
-
* @param cron 表达式字符串,一定要是包含6个以空格分离的字符
-
* @param lastTime 最近的执行时间
-
* @return long
-
* @throws
-
*/
-
public static long nextExecutionTime(String cron,long lastTime) {
-
Date date = new Date(lastTime);
-
CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cron);
-
Date nexDate = cronSequenceGenerator.next(date);
-
return nexDate.getTime();
-
}
-
-
public static void main(String[] args) {
-
String cron = "0/10 * * * * ? ";
-
System.out.println("当前时间:" + new Date().getTime());
-
System.out.println("下一次时间:" + nextExecutionTime(cron));
-
}
-
}
11.测试
-
package com.lyf.producerandconsumer;
-
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
import com.lyf.bean.TaskInfo;
-
import com.lyf.task.TaskService;
-
import com.lyf.util.SpringContextUtils;
-
-
/**
-
* @ClassName: TestMain
-
* @Description: 测试
-
* @author yanfei.li
-
* @date 2017年4月11日 下午6:20:30
-
* @Company:
-
*
-
*/
-
public class TestMain {
-
-
public static void main(String[] args) throws InterruptedException {
-
System.out.println("---------------");
-
ApplicationContext ac = new ClassPathXmlApplicationContext("com/lyf/task/local-spring.xml");
-
TaskInfo taskInfo = new TaskInfo();
-
taskInfo.setApi("MyTask");
-
taskInfo.setRunAt("some");
-
taskInfo.setCron("0/10 * * * * ?");//每隔10秒执行一次
-
taskInfo.setType("me");
-
System.out.println("++++++++++++++++" + ac);
-
TaskService taskService = (TaskService) SpringContextUtils.getBean("TaskService");
-
taskService.startTask(taskInfo);
-
-
System.out.println("===========" + taskService);
-
-
//主线程的死掉,不会影响其他线程的继续执行,除非是守护线程。
-
-
}
-
-
}
12.pom.xml
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0</modelVersion>
-
-
<groupId>com.lyf</groupId>
-
<artifactId>producerandconsumer</artifactId>
-
<version>0.0.1-SNAPSHOT</version>
-
<packaging>jar</packaging>
-
-
<name>producerandconsumer</name>
-
<url>http://maven.apache.org</url>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
</properties>
-
-
<dependencies>
-
<dependency>
-
<groupId>junit</groupId>
-
<artifactId>junit</artifactId>
-
<version>3.8.1</version>
-
<scope>test</scope>
-
</dependency>
-
-
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
-
<dependency>
-
<groupId>commons-beanutils</groupId>
-
<artifactId>commons-beanutils</artifactId>
-
<version>1.8.3</version>
-
</dependency>
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-aop</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-beans</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
-
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-context</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-core</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-tx</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-web</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
-
<dependency>
-
<groupId>org.springframework</groupId>
-
<artifactId>spring-expression</artifactId>
-
<version>4.0.4.RELEASE</version>
-
</dependency>
-
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
-
<dependency>
-
<groupId>aopalliance</groupId>
-
<artifactId>aopalliance</artifactId>
-
<version>1.0</version>
-
</dependency>
-
-
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
-
<dependency>
-
<groupId>org.aspectj</groupId>
-
<artifactId>aspectjweaver</artifactId>
-
<version>1.8.0</version>
-
</dependency>
-
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
-
<dependency>
-
<groupId>commons-logging</groupId>
-
<artifactId>commons-logging</artifactId>
-
<version>1.1.3</version>
-
</dependency>
-
</dependencies>
-
</project>
13.spring.xml
-
<?xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
-
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
-
xmlns:aop="http://www.springframework.org/schema/aop"
-
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
-
http://www.springframework.org/schema/aop
-
http://www.springframework.org/schema/aop/spring-aop.xsd ">
-
-
<!-- 启动注解扫描 -->
-
<context:annotation-config/>
-
<!-- 指定扫描的路径 -->
-
<context:component-scan base-package="com.lyf.*" >
-
<!-- 不对controller的注解 做处理,过滤掉,是为了和springmvc整合时,防止重复扫描,造成bean初始化2次-->
-
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
-
</context:component-scan>
-
-
<bean id="springUtils" class="com.lyf.util.SpringContextUtils"/>
-
-
<bean name="TaskService" class="com.lyf.task.TaskServiceImpl">
-
<constructor-arg>
-
<value>5</value>
-
</constructor-arg>
-
</bean>
-
-
-
</beans>
14.测试结果(每隔十秒执行一次,只贴出了部分打印数据)
-
++++++++++++++++org.springframework.context.support.ClassPathXmlApplicationContext@23e352bf: startup date [Wed Apr 12 11:44:46 GMT+08:00 2017]; root of context hierarchy
-
===========com.lyf.task.TaskServiceImpl@2f54745e
-
pop--------3621
-
MyTask--------------before-------------
-
MyTask--------------execute-------------
-
MyTask--------------after-------------
-
next===========9997
-
pop--------9997
-
MyTask--------------before-------------
-
MyTask--------------execute-------------
-
MyTask--------------after-------------
-
next===========9999
-
pop--------9999
-
MyTask--------------before-------------
-
MyTask--------------execute-------------
-
MyTask--------------after-------------
自己写的关于生产者与消费者模式,还有定时任务的demo的更多相关文章
- 使用libuv实现生产者和消费者模式
生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...
- java生产者与消费者模式
前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...
- condition版生产者与消费者模式
1.简介 在爬虫中,生产者与消费者模式是经常用到的.我能想到的比较好的办法是使用redis或者mongodb数据库构造生产者消费者模型.如果直接起线程进行构造生产者消费者模型,线程容易假死,也难以构造 ...
- Java并发编程(4)--生产者与消费者模式介绍
一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...
- Java多线程设计模式(2)生产者与消费者模式
1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...
- 【爬虫】Condition版的生产者和消费者模式
Condition版的生产者和消费者模式 threading.Condition 在没有数据的时候处于阻塞状态,有数据可以使用notify的函数通知等等待状态的线程运作 threading.Condi ...
- 【爬虫】Load版的生产者和消费者模式
''' Lock版的生产者和消费者模式 ''' import threading import random import time gMoney = 1000 # 原始金额 gLoad = thre ...
- java 线程并发(生产者、消费者模式)
线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...
- java进阶(40)--wait与notify(生产者与消费者模式)
文档目录: 一.概念 二.wait的作用 三.notify的作用 四.生产者消费者模式 五.举例 ---------------------------------------分割线:正文------ ...
随机推荐
- BZOJ3511: 土地划分(最小割)
Description Y国有N座城市,并且有M条双向公路将这些城市连接起来,并且任意两个城市至少有一条路径可以互达. Y国的国王去世之后,他的两个儿子A和B都想成为新的国王,但他们都想让这个国家更加 ...
- LuoguP4016 负载平衡问题(费用流)
题目描述 G 公司有 n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入输出格式 输入格式: ...
- readonly&&declare&&unset &&export&&env环境变量
readonly命令用于定义只读shell变量和shell函数.readonly命令的选项-p可以输出显示系统中所有定义的只读变量. 选项 -f:定义只读函数: -a:定义只读数组变量: -p:显示系 ...
- 【习题 8-10 UVA - 1614】Hell on the Markets
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 证明:前i个数一定能凑够1..sum[i]中的所有数字 i=1时显然成立. 现在假设i>=2时结论成立 即前i个数字能凑出1. ...
- ThinkPad E431 获取无限网络的驱动
sudo apt-get install linux-headers-generic build-essential dkms sudo apt-get install linux-source ...
- VMware虚拟机XP系统安装
转载:http://jingyan.baidu.com/article/54b6b9c00e2f452d593b4762.html
- LinearLayout -设置负值属性
1.我们调整两个控件的位置的时候,数值不仅仅是正数,负的也行,这时候只不过是跑到相对位置的另一边去了,例如 <ImageView android:id="@+id/image" ...
- 轻松学习Linux之Shell的常用过滤器
下载高清视频: http://down.51cto.com/data/157818 大小3:MB 时长: 7分钟 更多内容见: Linux爱好者的圣诞大餐-轻松学习Linux系列多媒体 ...
- Java学习笔记七 常用API对象三
一.泛型:简单说就是对对象类型进行限定的技术 public class GenericDemo { public static void main(String[] args){ /*泛型作为1.5版 ...
- 数组-reduce方法
转自: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/139 实现 convert 方法,把原始 list ...