- 浏览: 72077 次
- 性别:
- 来自: 北京
最新评论
-
zq3062211015:
想法很好。。万一 c就一个人下车 b很浪费啊
java并发学习之三:非阻塞漫想,关于环岛与地铁 -
zq3062211015:
楼主是大神,膜拜啊,不过有个地方说的不太对啊, if (poo ...
java并发学习之二:线程池(五) -
snake1987:
milk_36 写道终于找到是用java的了!LZ想问一下你们 ...
关于社交游戏中的同步服务器(长连接服务器) -
milk_36:
终于找到是用java的了!LZ想问一下你们项目中protobu ...
关于社交游戏中的同步服务器(长连接服务器) -
hobitton:
额,是我说的不准确哈,server不仅仅是options的集合 ...
java并发学习之二:线程池(四)
第二步,是实现一个线程池
因为之前看书的时候留了个心眼,看线程池相关的内容的时候特意没去研究JDK的实现
因为学跟做不是一码事,写一个线程池,算是给自己看完并发实践这书的一个练习吧
废话不多说,练习开始
首先,整理一下要实现的功能,或者说要注意的元素
1.实现Executor接口
2.实现一个等待队列(可否配置,优先级等)
3.是否需要预启动线程(可否配置)
4.执行开始前,结束后,需要留接口
5.Runable在任务中的存放形式
6.线程的启动,唤醒
7.线程池的关闭(优雅地结束),需要线程提供中断,线程池提供给使用者的提示,线程池返回取消线程等
8.线程队列(空闲队列?)
9.取空闲线程算法(任务入队时?线程执行一个任务结束时?)
10.将所有需要同步的地方尽量使用非阻塞算法(通过侦察,更新一个原子变量实现)
11.减少线程切换开销(轮询是否有任务,n微秒后再进入等待)
暂时就考虑到这些,剩下的以后再补
总的来说,计划写n个版本(毕竟是第二次动手,写一个庞大的需要细致考虑的东西功力还差远呢,只能从最简单的,最方便的实现开始,然后慢慢加强)
测试先行:
线程池代码:
第一版本的目标很简单,只要能跑,没死锁,就是完胜
可惜结果很让人绝望~
写完了,调了近3个小时,仍然没发现问题,最后加了一堆输出,又加了多个锁,终于勉勉强强跑起来了……
并发的调试真难,debug完全没用,看输出又看不出什么来,只能是一遍一遍地检查代码,写下一个版本前先找点资料,研究下调试方法吧
后来发现错误是一个简单的i++……
第一版本就写成这样了,之后再慢慢加强了,毕竟学java第一个玩意儿也是helloworld,原谅自己了
因为之前看书的时候留了个心眼,看线程池相关的内容的时候特意没去研究JDK的实现
因为学跟做不是一码事,写一个线程池,算是给自己看完并发实践这书的一个练习吧
废话不多说,练习开始
首先,整理一下要实现的功能,或者说要注意的元素
1.实现Executor接口
2.实现一个等待队列(可否配置,优先级等)
3.是否需要预启动线程(可否配置)
4.执行开始前,结束后,需要留接口
5.Runable在任务中的存放形式
6.线程的启动,唤醒
7.线程池的关闭(优雅地结束),需要线程提供中断,线程池提供给使用者的提示,线程池返回取消线程等
8.线程队列(空闲队列?)
9.取空闲线程算法(任务入队时?线程执行一个任务结束时?)
10.将所有需要同步的地方尽量使用非阻塞算法(通过侦察,更新一个原子变量实现)
11.减少线程切换开销(轮询是否有任务,n微秒后再进入等待)
暂时就考虑到这些,剩下的以后再补
总的来说,计划写n个版本(毕竟是第二次动手,写一个庞大的需要细致考虑的东西功力还差远呢,只能从最简单的,最方便的实现开始,然后慢慢加强)
测试先行:
public static void main(String[] args) throws InterruptedException { testEasyRunnableThreadPool(new ThreadPoolTest1(10), 10000, 10); testEasyRunnableThreadPool(Executors.newFixedThreadPool(10), 10000, 10); } /** * 一个产生随机数的方法,防止jvm优化 * @param seed * @return */ static int getRandomNum(int seed) { seed ^= (seed << 6); seed ^= (seed >>> 21); seed ^= (seed << 7); return seed; } /** * 执行一个简单的计算,只占用cpu,没有io和其他阻塞的方法 * @param pool * @param tryTime * @param threadNum * @throws InterruptedException */ static void testEasyRunnableThreadPool(Executor pool,int tryTime,int threadNum) throws InterruptedException { //construct runnable Runnable command = new Runnable() { public void run() { final int addTime = 1000000; long sum = 0; int temp = this.hashCode() ^ (int)System.currentTimeMillis(); for(int i = 0;i<addTime;i++) { sum += (temp = getRandomNum(temp)); } } }; testThreadPool(tryTime, pool, command); } /** * * @param tryNum * @param pool * @param commandList * @throws InterruptedException */ static void testThreadPool(int tryNum,Executor pool,final Runnable command) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(tryNum); Runnable wrapper = new Runnable() { public void run() { command.run(); //想测试并发,在并发中加入适当的同步操作是无法避免的,只能减少 //,在这,只是做了一个简单的countdown,影响不大 latch.countDown(); } }; long startTime = System.nanoTime(); for(int i = 0;i<tryNum;i++) { pool.execute(wrapper); } latch.await(); long endTime = System.nanoTime(); System.out.println(endTime-startTime); }
线程池代码:
第一版本的目标很简单,只要能跑,没死锁,就是完胜
可惜结果很让人绝望~
写完了,调了近3个小时,仍然没发现问题,最后加了一堆输出,又加了多个锁,终于勉勉强强跑起来了……
并发的调试真难,debug完全没用,看输出又看不出什么来,只能是一遍一遍地检查代码,写下一个版本前先找点资料,研究下调试方法吧
后来发现错误是一个简单的i++……
public class ThreadPoolTest1 implements Executor { //等待队列 Queue<Runnable> waitingQueue = null; ConcurrentLinkedQueue<ThreadNode> freeThread; //相当于一个freeThread的状态,根据状态决定行为,原则上将freeThread.size()+busyThreadsNum=MAXTHREADNUM private AtomicInteger busyThreadsNum = new AtomicInteger(0); //最大线程数 final int MAXTHREADNUM; public ThreadPoolTest1 (int threadNum) { this.MAXTHREADNUM = threadNum; init(MAXTHREADNUM,new ConcurrentLinkedQueue<Runnable>()); } private void init(int threadNum,ConcurrentLinkedQueue<Runnable> queue) { freeThread = new ConcurrentLinkedQueue<ThreadNode>(); waitingQueue = queue; //初始化空线程,一开始不是这样实现的,后来发现一堆问题,暂时只能先加锁,无论怎么样,跑起来再说把 synchronized(this) { for(int i = 0;i<threadNum;i++) { ThreadNode node = new ThreadNode(); busyThreadsNum.incrementAndGet(); node.start(); } } } private synchronized void threadExecute(Runnable command) { //用了个挺弱智的非阻塞算法 for(;;) { //得到开始的值 int expect = busyThreadsNum.get(); if(expect == MAXTHREADNUM) { waitingQueue.add(command); return; } else { //比较并设置,如果失败,重来 if(busyThreadsNum.compareAndSet(expect, ++expect))//之前写的是expect++,检查了n久,硬是看不出啥问题,只能怪自己天资愚鲁吧 { ThreadNode t = freeThread.remove(); t.setCommand(command); synchronized(t) {t.notify();} return; } else continue; } } } private class ThreadNode extends Thread { Runnable command = null; Exception e = null; Exception getException() { return e; } void setCommand(Runnable c) { command = c; } @Override public void run() { try { for(;;) { if(command == null) { ThreadPoolTest1.this.waitThread(this); } command.run(); command = ThreadPoolTest1.this.getCommand(); } }catch (InterruptedException e) { } } } Runnable getCommand() throws InterruptedException { return waitingQueue.poll(); } void waitThread(Thread t) throws InterruptedException { synchronized(this) { freeThread.add((ThreadNode) t); busyThreadsNum.decrementAndGet(); } synchronized(t) { t.wait(); } } protected void beforeExecute() { } public void execute(Runnable command) { beforeExecute(); threadExecute(command); afterExecute(); } protected void afterExecute() { } }
第一版本就写成这样了,之后再慢慢加强了,毕竟学java第一个玩意儿也是helloworld,原谅自己了
发表评论
-
关于jdk7的aio
2012-11-28 13:59 0最近耳边老有人提jdk7的 ... -
关于锁的两个小技巧
2012-09-03 14:55 1373现在我们的开发中越来越多用锁的情况,锁其实比cas恐怖很多,像 ... -
关于java hotspot vm的server版和client版的一点小事
2012-09-03 14:53 4041我们知道,java的虚拟器其实是有两个版本的, client ... -
关于游戏脚本
2012-09-03 14:43 2217社交游戏其实不是太需 ... -
关于社交游戏中的同步服务器(长连接服务器)
2012-09-03 14:39 7464博客好久没打理了,今 ... -
关于游戏中的同步服务器(长连接服务器)
2012-09-03 14:33 1博客好久没打理了,今 ... -
BTrace实践
2011-10-13 15:30 0一直都在关注java的profile工具,这几天发现了这个好东 ... -
项目回忆(一):虚拟房间系统
2011-09-23 14:34 1403需求: 1.硬件环境:所有 ... -
近月学习记录(四)
2011-09-12 12:48 0基于netty的同步游戏服 ... -
近月学习记录(三)
2011-09-10 15:01 0最近在用netty做一个交 ... -
protobuf深入分析
2011-07-22 19:31 0公司用了protobuf,在日常工作中都有所接触,一直没有时间 ... -
近月学习记录(二)
2011-06-12 22:30 01.maven maven其实不难,但是一开始学习的时候的确感 ... -
近月学习记录(一)
2011-06-12 22:27 2421最近换了一个公司,确 ... -
java并发学习之二:线程池(五)
2011-04-17 13:31 2628之前的线程池已实现了基本的功能:运行每一个线程,而且测试了一下 ... -
java并发学习之六:JCSP(Java Communicating Sequential Processes)实践
2011-04-13 11:32 5824首先得描述下什么是JCSP ... -
java并发学习之二:线程池(四)
2011-04-12 17:43 2364一直都知道有两个jvm,一个是server,一个是client ... -
java并发学习之二:线程池(三)
2011-04-08 16:24 2229没找到什么好工具,也没得到好建议,好技巧,只能自己摸索了 一 ... -
java并发学习之五:读JSR133笔记
2011-04-06 11:33 10862在写线程池的时候,遇到了很多的问题,特别是happen-bef ... -
java并发学习之四:JSR 133 (Java Memory Model) FAQ【译】
2011-04-01 16:52 4029Jsr133地址:http://www.c ... -
java并发学习之三:非阻塞漫想,关于环岛与地铁
2011-03-27 21:10 1771到过北京上地的都会知道,上地城铁往西走有一个很大的上地环岛,旁 ...
相关推荐
Java并发编程:线程池的使用 - 平凡希 - 博客园平凡希博客园首页联系管理随笔 - 127 文章 - 1 评论 - 94Java并发编程:线程池的使用在前面
而了解 Java 并发编程以及其中的 JUC(java.util.concurrent)线程池,对于构建高性能、高可伸缩性的应用程序具有重要意义。 多核处理器的出现使得并发执行成为一种重要的优化手段。了解并发编程和线程池的工作原理...
Java 并发学习笔记: 进程和线程, 并发理论, 并发关键字, Lock 体系, 原子操作类, 发容器 & 并发工具, 线程池, 并发实践 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的...
java并发学习总结 例子:包含(并发容器、同步容器、同步工具、死锁、异常、中断、线程池、返回结果、同步方法等代码例子)
Java分布式应用学习笔记07线程池应用
Java并发编程与高并发解决方案:线程池,消息队列,服务拆分,限流,降级,熔断思路,数据库分表
23 高并发编程和线程池,教程视频:java中高并发编程和线程池
聊聊并发(3)Java线程池的分析和使用Java开发Java经验技巧共7页.pdf.zip
java并发笔记
Java并发编程常见知识点源码集锦,涉及到对象锁,Executors多任务线程框架,线程池等示例,列出一些源码包中包括的内容: volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小...
书籍:如《Java并发编程实战》、《Concurrency in C++》等。 官方文档:不同编程语言的官方文档通常会提供关于并发编程的指南和最佳实践。 社区和论坛:如Stack Overflow、Reddit等,可以提供实际问题的帮助和讨论。
当调用 start 启动线程时 Java 虚拟机会调 用该类的 run方法。 那么该类的 run() 方法中就是调用了 Runnable 对象的 run() 方法。 我 们可以继承重写Thread 类,在其 start 方法中添加不断循环调用传递过来的 ...
第二部分 结构化并发应用程序 第6章 任务执行 6.1 在线程中执行任务 6.1.1 串行地执行任务 6.1.2 显式地为任务创建线程 6.1.3 无限制创建线程的不足 6.2 Executor框架 6.2.1 示例:基于Executor的Web服务器 ...
阿里专家级并发编程架构师级课程,完成课程的学习可以帮助同学们解决非常多的JAVA并发编程疑难杂症,极大的提高JAVA并发编程的效率。课程内容包括了JAVA手写线程池,UC线程池API详解,线程安全根因详解,锁与原子类...
第4节学习并发的四个阶段并推荐学习并发的资料 [免费观看] 00:09:13分钟 | 第5节线程的状态以及各状态之间的转换详解00:21:56分钟 | 第6节线程的初始化,中断以及其源码讲解00:21:26分钟 | 第7节多种创建线程的...
java代码 ThreadPoolExecutor线程池并发测试例子如有误欢迎指正
《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时...
Java并发编程的艺术 作者:方腾飞 魏鹏 程晓明 著 丛书名:Java核心技术系列 出版日期 :2015-07-25 ISBN:978-7-111-50824-3 第1章介绍Java并发编程的挑战,向读者说明进入并发编程的世界可能会遇到哪些问题,以及如何...
《Java并发编程从入门到精通》内容包括并发编程概念,线程,线程安全,线程集合类,线程阀,线程池,Fork/Join,线程、线程池在互联网项目开发的应用,线程监控及线程分析,Android中线程应用。 本书适合Java开发...
java多线程并发查询数据库,使用线程池控制分页,并发查询。