今天突然需要用到线程池来解决一个问题,但是已经很久没有写关于线程的程序了,记忆中曾经记忆深刻的线程池demo似乎也已经模糊起来。事实证明了一句话,学知识就得温故而知新,随着时间的流逝,记忆中的知识也会慢慢消退,只有通过不断的回顾,不断的思考才能将知识用的随心所欲,随时需要,随时便可信手拈来。
虽然今天遇到的问题在百度的帮助下顺利得到解决,但是,回来还是不甘心的找了好久以前写的源码,真心觉得还是值得细细品味。最开始接触线程时,也和很多朋友一样,里面有太多的问号,虽然听得比较多,但是就实际应用却难以开始在代码上实现。今天就把源码贴出来,供自己时时温习,与此同时也给新朋友提供一个线程的入门案例,以便更能理解这项相当有特色的技术。
首先还是介绍一下线程和线程池吧,我并没有详细地去研究过线程和线程池,所以在此谈的就是自己的看法和理解,不会像书中所说的那么高深,说实话,对于一个刚刚接触线程的人来说,看书是真心看不懂,讲的专业术语太多,很难理解。但是也不排除一些特别擅长看书的人,他们就对书上的内容很容易接受,这也是相比较于那些实际动手的人而言。
在现在的很多应用中都需要线程来完成任务,如果线程越多,那么完成任务所用的时间就越少,前提是线程数量也得合适才行,如果单时间内产生大量的线程可能会是系统的内存突然达到其极限值,这是很不好的。线程池无非就是在最开始得时候就放很多线程在那里,需要的时候直接去拿就行。这好像又和连接池有点类似。线程的种类确实比较多,我也不列举了,愿意了解的可以百度,贴出实现源码demo,体验一番线程和多线程的魅力:
1. 新建web工程:在这里通过web.xml中Servlet的<load-on-startup>来启动线程,当demo一旦在tomcat中被启动,线程池就会立刻运行,执行在开始给他分配的任务。
项目包结构如下:
2. Web.xml中的源码:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>InitSevlet</servlet-name> <servlet-class>init.InitSevlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>InitSevlet</servlet-name> <url-pattern>/servlet/InitSevlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
3. Servlet中源码:
package init; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import util.Threadpool; import work.MainWork; import work.SingleWork; public class InitSevlet extends HttpServlet { private static final long serialVersionUID = -5708566856710493294L; public void destroy() { super.destroy(); } public void init() throws ServletException { MainWork mainWork = new MainWork("Red"); MainWork mainWork1 = new MainWork("Blue"); MainWork mainWork2 = new MainWork("Gray"); MainWork mainWork3 = new MainWork("张三"); MainWork mainWork4 = new MainWork("李四"); SingleWork SingleWork = new SingleWork("Red"); SingleWork SingleWork1 = new SingleWork("Blue"); SingleWork SingleWork2 = new SingleWork("Gray"); SingleWork SingleWork3 = new SingleWork("张三"); SingleWork SingleWork4 = new SingleWork("李四"); List<MainWork> list = new ArrayList<MainWork>(); list.add(mainWork); list.add(mainWork); list.add(mainWork); list.add(mainWork); list.add(mainWork); list.add(mainWork); list.add(SingleWork); list.add(SingleWork1); list.add(mainWork1); list.add(SingleWork2); list.add(mainWork2); list.add(SingleWork3); list.add(mainWork3); list.add(mainWork4); list.add(SingleWork4); ExecutorService threadpool = Threadpool.getInstance(); try { List<Future<Object>> lists = threadpool.invokeAll(list); } catch (InterruptedException e) { e.printStackTrace(); } } }
4. 线程池的定义类:
package util; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Threadpool { private static volatile ExecutorService threadpool; private final static int THREADCOUNT = 5; //线程池数量 public Threadpool() { } public static synchronized ExecutorService getInstance() { if (null == threadpool) { threadpool = Executors.newFixedThreadPool(THREADCOUNT); } return threadpool; } }
5. 两个任务中需要注意的就是他们的继承不一样,SingleWork extends MainWork ;MainWork implements java.io.Serializable, Callable<Object>
MainWork.java
package work; import java.util.concurrent.Callable; public class MainWork implements java.io.Serializable, Callable<Object> { private static final long serialVersionUID = 9092827859545735164L; public MainWork() { } public MainWork(String workname) { this.workname = workname; } private String workname; public String getWorkname() { return workname; } public void setWorkname(String workname) { this.workname = workname; } public Object call() throws Exception { System.out.println("hello, " + getWorkname()); Thread.sleep(5000); // 睡眠5秒 return null; } }
SingleWork .java
package work; public class SingleWork extends MainWork { private static final long serialVersionUID = -6170744685310914685L; private String name; public SingleWork() { } public SingleWork(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Object call() throws Exception { System.out.println("hi, " + getName()); return null; } }
5. 程序运行结果:
贴源码于此,反复理解,反复学习。
能通过坚持去解决的问题,那就拼着命咬着牙坚持下去。
邮箱:it_red@sina.com
个人博客: http://itred.cnblogs.com 网站: http://wangxingyu.jd-app.com
版权声明:本文版权归作者和博客园共有,欢迎转载,但请在文章显眼位置标明文章出处。未经本人书面同意,将其作为他用,本人保留追究责任的所有权利。