多线程+队列提高程序执行效率

前言

在现在的大型分布式系统中,接口要处理的访问并发次数可能会十分的庞大,在Java中开发者应对这样的情况,在并发量较大的业务中都会使用线程池技术,以期达到增加接口的响应速度的效果!试想一件事本来只有一个人在累死累活的做,现在突然多出来二十个人一起做,那么时间会不会大大的缩短了。当然如果使用不当,人和人之间产生矛盾什么的,会不会反而起到负面作用呢?二十个人他们什么时候干活什么时候收工,是不是也要个统一的管理者呢?

案例

需要有线程基础,队列基础,线程池的基础!

使用线程池+队列做一个生产消费的案例!创建一个队列的统一资源管理类:

package com.study.store;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class TaskManager {
	public static BlockingQueue<String> blockingQueue;
	
	private TaskManager() {
		blockingQueue = new LinkedBlockingQueue<String>();
	}
	
	private static volatile TaskManager instance;
	
	public static TaskManager getInstance() {
		if(instance == null) {
			synchronized (TaskManager.class) {
				if(instance == null) {
					instance = new TaskManager();
				}
			}
		}
		return instance;
	}
	
	/**
	 * put -- 模拟任务生产 -- (场景应用在单线程下,put进有效的url地址)
	 */
	public static void produce(String url) throws InterruptedException {
		blockingQueue.put(url);
	}
	
	/**
	 * take -- 模拟任务消费 -- (场景应用在多线程下,take取出有效的url并进行后期处理)
	 */
	public static String consume() throws InterruptedException {
		return blockingQueue.take();
	}
	
	/**
	 * 获取队列的url数量 -- (如果这个值在10s内,等于0的话,将会终止所有任务 -- 生成线程 和 消费线程)
	 */
	public Integer getSize() {
		return blockingQueue.size();
	}
}

这个例子应该没什么好说的,dcl单例模式,生产与消费的方法!

生产者:

package com.study.store;

public class Producer implements Runnable {

	private String name;
	private String url;
	public Producer(String name, String url, TaskManager taskManager) {
		this.name = name;
		this.url = url;
	}

	@Override
	public void run() {
		try {
			while (true) {
				// 生产url
				System.out.println("生产者[" + name + "]:生产url --" + url);
				TaskManager.produce(url);
				// 休眠300ms -- 观看效果
				Thread.sleep(3000);
			}
		} catch (InterruptedException ex) {
			System.err.println("Producer Interrupted:" + ex.getMessage());
		}
	}

}

消费者:

package com.study.store;

public class Consumer implements Runnable {

	private String name;
	private TaskManager taskManager;

	public Consumer(String name, TaskManager taskManager) {
		this.name = name;
		this.taskManager = taskManager;

	}

	@Override
	public void run() {
		while (true) {
			// 消费url
			try {
				System.err.println(
						"消费者[" + name + "]:消费url --" + TaskManager.consume() + "--剩余url容量:" + taskManager.getSize());

			} catch (InterruptedException e) {
				System.err.println("Consumer Interrupted :" + e.getMessage());

			}
		}
	}
}

客户端:

创建两个生产者对象, 四个消费者,模拟生产者生产,消费者做即时消费:

package com.study.store;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Client {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		TaskManager manager = TaskManager.getInstance();

		/**
		 * 来一个Java的线程池 CachedThreadPool会创建一个缓存区,将初始化的线程缓存起来 如果线程有可用的,就使用之前创建好的线程
		 * 如果没有可用的,就新创建线程 终止并且从缓存中移除已有60秒未被使用的线程
		 */
		ExecutorService service = Executors.newCachedThreadPool();
		Producer producer1 = new Producer("生产者A", "http://www.baidu.com1", manager);
		Producer producer2 = new Producer("生产者B", "http://www.baidu.com2", manager);
		Consumer consumer1 = new Consumer("消费者1", manager);
		Consumer consumer2 = new Consumer("消费者2", manager);
		Consumer consumer3 = new Consumer("消费者3", manager);
		Consumer consumer4 = new Consumer("消费者4", manager);
		long start = System.currentTimeMillis();
		for (int i = 0; i < 200; i++) {
//			manager.produce("http://www.baidu.com-" + Integer.valueOf(i));
			service.submit(producer1);
			service.submit(producer2);
		}

		
		
		service.submit(consumer1);
		service.submit(consumer2);
		service.submit(consumer3);
		service.submit(consumer4);
		
		/**
		 * 来10打消费者 -- 模拟从队列管理器中取出url并进行资源下载
		 
		for (int i = 0; i < 10; i++) {
			String name = "消费者:" + Integer.valueOf(i);
			service.submit(new Consumer(name, manager));
			
		}*/
		while (true) {
			Thread.sleep(1000 * 10);
			// 主线程 每10秒检测一次,如果检测到任务队列里长时间没有内如put,就终止整个任务service
			if (manager.getSize() == 0) {
				service.shutdown();
				break;
			}
		}
		long end = System.currentTimeMillis();
		System.err.println("下载任务完成!耗时:" + (end - start) + "");

	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值