`

使用java.util.concurrent实现的线程池、消息队列功能

阅读更多

ThreadPoolManager类:负责管理线程池,调用轮询的线程来访问字符串缓冲区的内容,维护缓冲区,当线程池溢出时抛出的Runnable任务被加入到字符缓冲区。

  public class ThreadPoolManager

  {

  private static ThreadPoolManager tpm = new ThreadPoolManager();

  // 线程池维护线程的最少数量

  private final static int CORE_POOL_SIZE = 4;

  // 线程池维护线程的最大数量

  private final static int MAX_POOL_SIZE = 10;

  // 线程池维护线程所允许的空闲时间

  private final static int KEEP_ALIVE_TIME = 0;

  // 线程池所使用的缓冲队列大小

  private final static int WORK_QUEUE_SIZE = 10;

  // 消息缓冲队列

  Queue msgQueue = new LinkedList();

  // 访问消息缓存的调度线程

  final Runnable accessBufferThread = new Runnable()

  {

  public void run()

  {

  // 查看是否有待定请求,如果有,则创建一个新的AccessDBThread,并添加到线程池中

  if( hasMoreAcquire() )

  {

  String msg = ( String ) msgQueue.poll();

  Runnable task = new AccessDBThread( msg );

  threadPool.execute( task );

  }

  }

  }

 final RejectedExecutionHandler handler = new RejectedExecutionHandler()

  {

  public void rejectedExecution( Runnable r, ThreadPoolExecutor executor )

  {

  System.out.println(((AccessDBThread )r).getMsg()+"消息放入队列中重新等待执行");

  msgQueue.offer((( AccessDBThread ) r ).getMsg() );

  }

  };

  // 管理数据库访问的线程池

  final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(

  CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,

  new ArrayBlockingQueue( WORK_QUEUE_SIZE ), this.handler );

  // 调度线程池

  final ScheduledExecutorService scheduler = Executors

  .newScheduledThreadPool( 1 );

  final ScheduledFuture taskHandler = scheduler.scheduleAtFixedRate(

  accessBufferThread, 0, 1, TimeUnit.SECONDS );

  public static ThreadPoolManager newInstance()

  {

  return tpm;

  }

  private ThreadPoolManager(){}

  private boolean hasMoreAcquire()

  {

  return !msgQueue.isEmpty();

  }

 public void addLogMsg( String msg )

  {

  Runnable task = new AccessDBThread( msg );

  threadPool.execute( task );

  }

  }

  public class AccessDBThread implements Runnable

  {

  private String msg;

  public String getMsg()

  {

  return msg;

  }

  public void setMsg( String msg )

  {

  this.msg = msg;

  }

  public AccessDBThread(){

  super();

  }

  public AccessDBThread(String msg){

  this.msg = msg;

  }

  public void run()

  {

  // 向数据库中添加Msg变量值

  System.out.println("Added the message: "+msg+" into the Database");

  }

  }

  public class TestDriver

  {

  ThreadPoolManager tpm = ThreadPoolManager.newInstance();

  public void sendMsg( String msg )

  {

  tpm.addLogMsg( msg + "记录一条日志 " );

  }

  public static void main( String[] args )

  {

  for( int i = 0; i < 100; i++ )

  {

  new TestDriver().sendMsg( Integer.toString( i ) );

  }

  }

  }

 成功地编译Java applet之后生成响应的字节码文件HelloWorld.class的文件。用资源管理器或DIR命令列出目录列表,将会发现目录C:\ghq中多了一个名为HelloWorld.class的文件。

  (3)创建HTML文件

  在运行创建的HelloWorld.class 之前,还需创建一个HTML文件,appletviewer或浏览器将通过该文件访问创建的Applet。为运行HelloWorld.class, 需要创建包含如下HTML语句的名为HelloWorld.html的文件。

  <HTML>

  <TITLE>HelloWorld! Applet</TITLE>

  <APPLET

  CODE="JavaWorld.class"

  WIDTH=200

  HEIGHT=100>

  </APPLET>

  </HTML>

  本例中,<APPLET>语句指明该Applet字节码类文件名和以像素为单位的窗口的尺寸。虽然这里HTML文件使用的文件名为 HelloWorld.HTML,它对应于HelloWorld.java的名字,但这种对应关系不是必须的,可以用其他的任何名字(比如说 Ghq.HTML)命名该HTML文件。但是使文件名保持一种对应关系可给文件的管理带来方便。

  (4)执行 HelloWorld.html

  如果用appletviewer运行HelloWorld.html,需输入如下的命令行:

  C:\ghq\>appletviewer JavaWorld.html<ENTER>

  可以看出,该命令启动了appletviewer并指明了HTML文件,该HTML文件中包含对应于HelloWorld 的<APPLET>语句。

  如果用浏览器运行HelloWorld Applet,需在浏览器的地址栏中输入HTML文件URL地址。

  至此,一个Applet程序的开发运行整个过程结束了(包括java源文件、编译的class文件、html文件以及用appletviewer或用浏览器运行)。

  (二) Applet类

  Applet类是所有Applet应用的基类,所有的Java小应用程序都必须继承该类。如下所示。

  import java. applet.*;

  public class OurApplet extends Applet

  {

  ......

  ......

  }

  Applet类的构造函数只有一种,即:public Applet()

  Applet实现了很多基本的方法,下面列出了Applet类中常用方法和用途。

  public final void setStub(AppletStub stub)

  //设置Applet的stub.stub是Java和C之间转换参数并返回值的代码位,它是由系统自动设定的。

  public boolean isActive();// 判断一个Applet是否处于活动状态。

  public URL getDocumentBase();// 检索表示该Applet运行的文件目录的对象。

  public URL getCodeBase();// 获取该Applet 代码的URL地址。

  public String getParameter(String name);// 获取该Applet 由name指定参数的值。

  public AppletContext getAppletContext();// 返回浏览器或小应用程序观察器。 <script src="/ggao/news_js/MyClass_it.js"></script>

 

public void resize(int width,int height);// 调整Applet运行的窗口尺寸。

  public void resize(Dimension d);// 调整Applet运行的窗口尺寸。

  public void showStatus(String msg);// 在浏览器的状态条中显示指定的信息。

  public Image getImage(URL url); // 按url指定的地址装入图象。

  public Image getImage(URL url,String name);// 按url指定的地址和文件名加载图像。

  public AudioClip getAudioClip(URL url);// 按url指定的地址获取声音文件。

public AudioClip getAudioClip(URL url, String name);// 按url指定的地址和文件名获取声音。

  public String getAppletInfo();// 返回Applet应用有关的作者、版本和版权方面的信息;

  public String[][] getParameterInfo();

  // 返回描述Applet参数的字符串数组,该数组通常包含三个字符串: 参数名、该参数所需值的类型和该参数的说明。

  public void play(URL url);// 加载并播放一个url指定的音频剪辑。

  public void destroy();//撤消Applet及其所占用的资源。若该Applet是活动的,则先终止该Applet的运行。

  (1) Applet运行状态控制基本方法

  Applet类中的四种基本方法用来控制其运行状态:init()、start()、stop()、destroy()

  init()方法

  这个方法主要是为Applet的正常运行做一些初始化工作。当一个Applet被系统调用时,系统首先调用的就是该方法。通常可以在该方法中完成从网页向Applet传递参数,添加用户界面的基本组件等操作。

  start()方法

  系统在调用完init()方法之后,将自动调用start()方法。而且,每当用户离开包含该Applet的主页后又再返回时,系统又会再执行一遍start()方法。这就意味着start()方法可以被多次执行,而不像init()方法。因此,可把只希望执行一遍的代码放在init()方法中。可以在start()方法中开始一个线程,如继续一个动画、声音等。

  stop()方法

  这个方法在用户离开Applet所在页面时执行,因此,它也是可以被多次执行的。它使你可以在用户并不注意Applet的时候,停止一些耗用系统资源的工作以免影响系统的运行速度,且并不需要人为地去调用该方法。如果Applet中不包含动画、声音等程序,通常也不必实现该方法。

  destroy()方法

  与对象的finalize()方法不同,Java在浏览器关闭的时候才调用该方法。Applet是嵌在HTML文件中的,所以 destroty()方法不关心何时Applet被关闭,它在浏览器关闭的时候自动执行。在destroy()方法中一般可以要求收回占用的非内存独立资源。(如果在Applet仍在运行时浏览器被关闭,系统将先执行stop()方法,再执行destroy()方法。

  (2) Applet应用的有关参数说明

  利用Applet来接收从HTML中传递过来的参数,下面对这些参数作一简单说明:

  * CODE标志

  CODE标志指定Applet的类名;WIDTH和HEIGHT标志指定Applet窗口的像素尺寸。在APPLET语句里还可使用其他一些标志。

  * CODEBASE 标志

  CODEBASE标志指定Applet的URL地址。Applet的通用资源定位地址URL,它可以是绝对地址 ,如www.sun.com。也可以是相对于当前HTML所在目录的相对地址,如/AppletPath/Name。如果HTML文件不指定CODEBASE 标志,浏览器将使用和HTML文件相同的URL。

  * ALT 标志

  虽然Java在WWW上很受欢迎,但并非所有浏览器都对其提供支持。如果某浏览器无法运行Java Applet,那么它在遇到APPLET语句时将显示ALT标志指定的文本信息。

  * ALIGN 标志

  ALIGN标志可用来控制把Applet窗口显示在HTML文档窗口的什么位置。与HTML<LMG>语句一样,ALIGN标志指定的值可以是TOP、MIDDLE或BOTTOM。

  * VSPACE与HSPACE 标志

  VSPACE和HSPACE标志指定浏览器显示在Applet窗口周围的水平和竖直空白条的尺寸,单位为像素。如下例使用该标志在Applet窗口之上和之下各留出50像素的空白,在其左和其右各留出25像素的空白:

  * NAME 标志

  NAME标志把指定的名字赋予Applet的当前实例。当浏览器同时运行两个或多个Applet时,各Applet可通过名字相互引用或交换信息。如果忽略NAME标志,Applet的名字将对应于其类名。

  * PARAM 标志

  通用性是程序设计所追求的目标之一。使用户或者程序员能很方便地使用同一个Applet完成不同的任务是通用性的具体表现。从HTML文件获取信息是提高Applet通用性的一条有效途径。

  假设编制了一个把某公司的名字在屏幕上卷动的Applet。为了使该Applet更加通用,则可以使该Applet从HTML文件获取需要卷动的文本信息。这样,若想显示另一个公司的名字,用不着修改Java Applet本身,只需修改HTML文件即可。

  PARAM 标志可用来在HTML文件里指定参数,格式如下所示:

分享到:
评论
1 楼 ujnlu 2011-08-09  
什么时候能来几篇原创的呢

相关推荐

    java.util.concurrent 实现线程池队列

    java.util.concurrent 使用jdk内置的包实现一个线程池的操作

    java并发工具包 java.util.concurrent中文版用户指南pdf

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf

    java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    浅谈java.util.concurrent包中的线程池和消息队列

    主要介绍了浅谈java.util.concurrent包中的线程池和消息队列,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版

    本资源包含两个 pdf 文档,一本根据 Jakob Jenkov 最新博客 (http://tutorials.jenkov.com/java-util-concurrent/index.html) 整理的 java_util_concurrent_user_guide_en.pdf,一个中文翻译的 java_util_concurrent...

    Java网络编程精解之ServerSocket用法详解

    在客户/ 服务器通信模式中, 服务器端需要创建监听特定端口的 ServerSocket , ServerSocket 负责接收客户连接请求。...章还介绍了 java.util.concurrent 包中的线程池类的用法,在服务器程序中可以直接使用它们。

    java并发工具包详解

    1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...

    java并发包资源

    本资源包含两个 pdf 文档,一本根据 Jakob Jenkov 最新博客 (http://tutorials.jenkov.com/java-util-concurrent/index.html) 整理的 java_util_concurrent_user_guide_en.pdf,一个中文翻译的 java_util_concurrent...

    ServerSocket用法详解

    ServerSocket用法详解 提供线程池的一种实现方式。线程池包括一个工作队列和若干工作线程。服务器程 序向工作队列中加入与客户...介绍了java.util.concurrent包中的线程池类的用法,在服务器程序中可以直接使用它们。

    Executor,Executors,ExecutorService比较.docx

    Executors: 是java.util.concurrent包下的一个类,提供了若干个静态方法,用于生成不同类型的线程池。Executors一共可以创建下面这四类线程池: 1.newFixedThreadPool创建一个可缓存线程池,如果线程池长度超过...

    java核心知识点整理.pdf

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    customcode:至

    具有java.util.concurrent。*构造的自定义实现 CountDownLatch 循环屏障 换货商 重入锁 读锁 信号 线程池 BlockingQueue-生产者消费者 具有一些集合类的自定义实现 有以下示例代码 易挥发的 僵局 java.util....

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    并发容器和线程池,java并发编程3

    JDK提供的这些容器⼤部分在java.util.concurrent包中。我们挑选出⼀些⽐较有代表性的并发容器 1 类,来感受⼀下JDK⾃带的并发集合带来的“快感”。 ConcurrentLinkedQueue是⼀个基于链接节点的⽆界线程安全队列,它...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【多线程】简述synchronized 和java.util.concurrent.locks.Lock的异同? 90 【线程】ThreadLocal的作用 90 【Spring】什么是IOC和DI?DI是如何实现的 91 【Spring】spring中的IOC(控制反转)的原理 92 【Spring】...

    Java并发编程实战

    14.6 java.util.concurrent同步器类中的 AQS257 14.6.1 ReentrantLock257 14.6.2 Semaphore与CountDownLatch258 14.6.3 FutureTask259 14.6.4 ReentrantReadWriteLock259 第15章 原子变量与非阻塞同步机制261 ...

Global site tag (gtag.js) - Google Analytics