Java工作队列和线程池

简介:   分类: 【java】2013-11-21 20:29 917人阅读 评论(3) 收藏 举报 背景   最近的需要做一个与设备通信的web项目。当然,我们需要写好与设备之间的通信协议(socket)。

 

分类: 【java】
背景
   最近的需要做一个与设备通信的web项目。当然,我们需要写好与设备之间的通信协议(socket)。大致的时序逻辑时:当用户用浏览器点击页面某一控件后,它就向后台发送一个post请求,后台解析前台发送的参数,然后封装成相应的帧格式,然后与设备进行通信,设备接到指令后,完成相应的功能,然后将数据信息返回给后台服务器,后台服务器将这些返回的数据组织好,一方面返回给前台页面,一方面将数据存储到数据库中。
问题:
1.由于通信设备只允许一个socket与它通信,因此,所有的用户都需要共用一个socket,所以,在某一时刻,不能有2个用户同时使用socket

2.当很多条相同的指令以较短的时间间隔(1s左右)发送到通信设备时,通信设备只响应第一条,其他的不予响应。

解决方案

针对上述问题,我们就会想到通过使用队列和线程池来解决以上问题。我们可以将所有用户的指令依次放入队列中,线程池中只允许一个线程运行,而且线程执行完之后,还可以休眠一段时间,等通信设备反应过来的时候,再依次执行队列中的指令。

队列和线程池演示程序

1.WorkQueue.java

该类实现了队列和线程池,详见如下

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 
  2.  * $filename: WorkQueue.java,v $ 
  3.  * $Date: 2013-11-20  $ 
  4.  * Copyright (C) ZhengHaibo, Inc. All rights reserved. 
  5.  * This software is Made by Zhenghaibo. 
  6.  */  
  7. package edu.njupt.zhb;  
  8.   
  9. import java.util.LinkedList;  
  10.   
  11. /* 
  12.  *@author: ZhengHaibo   
  13.  *web:     http://blog.csdn.net/nuptboyzhb 
  14.  *mail:    zhb931706659@126.com 
  15.  *2013-11-20  Nanjing,njupt,China 
  16.  *References:http://www.ibm.com/developerworks/java/library/j-jtp0730/index.html 
  17.  */  
  18. public class WorkQueue  
  19. {  
  20.     private final int nThreads;//同时最多执行的线程个数  
  21.     private final PoolWorker[] threads;//线程池  
  22.     private final LinkedList queue;//线程队列  
  23.   
  24.     public WorkQueue(int nThreads)  
  25.     {  
  26.         this.nThreads = nThreads;  
  27.         queue = new LinkedList();  
  28.         threads = new PoolWorker[nThreads];  
  29.   
  30.         for (int i=0; i<nThreads; i++) {  
  31.             threads[i] = new PoolWorker();  
  32.             threads[i].start();  
  33.         }  
  34.     }  
  35.   
  36.     public void execute(Runnable r) {  
  37.         synchronized(queue) {  
  38.             queue.addLast(r);  
  39.             queue.notify();  
  40.         }  
  41.     }  
  42.   
  43.     private class PoolWorker extends Thread {  
  44.         public void run() {  
  45.             Runnable r;  
  46.   
  47.             while (true) {  
  48.                 synchronized(queue) {  
  49.                     while (queue.isEmpty()) {  
  50.                         try  
  51.                         {  
  52.                             queue.wait();  
  53.                         }  
  54.                         catch (InterruptedException ignored)  
  55.                         {  
  56.                         }  
  57.                     }  
  58.   
  59.                     r = (Runnable) queue.removeFirst();  
  60.                 }  
  61.   
  62.                 // If we don't catch RuntimeException,   
  63.                 // the pool could leak threads  
  64.                 try {  
  65.                     r.run();  
  66.                 }  
  67.                 catch (RuntimeException e) {  
  68.                     // You might want to log something here  
  69.                     e.printStackTrace();  
  70.                 }  
  71.             }  
  72.         }  
  73.     }  
  74. }  

2.WorkThread.java 

 

这是我们的工作线程,在这个Demo中,工作线程只做一件事:将number的值加1,然后休眠,最后打印一下当前number的值。由于number是静态变量,因此我们就可以模拟一下,工作队列的一个执行情况。

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 
  2.  * $filename: WorkThread.java,v $ 
  3.  * $Date: 2013-11-20  $ 
  4.  * Copyright (C) ZhengHaibo, Inc. All rights reserved. 
  5.  * This software is Made by Zhenghaibo. 
  6.  */  
  7. package edu.njupt.zhb;  
  8. /* 
  9.  *@author: ZhengHaibo   
  10.  *web:     http://blog.csdn.net/nuptboyzhb 
  11.  *mail:    zhb931706659@126.com 
  12.  *2013-11-20  Nanjing,njupt,China 
  13.  */  
  14. public class WorkThread extends Thread{  
  15.     public static int number = 0;  
  16.     @Override  
  17.     public void run() {  
  18.         // TODO Auto-generated method stub  
  19.         try {  
  20.             number = number + 1;  
  21.             Thread.sleep(100);  
  22.             System.out.println("number = "+number);  
  23.         } catch (Exception e) {  
  24.             // TODO Auto-generated catch block  
  25.             e.printStackTrace();  
  26.         }  
  27.     }  
  28.       
  29. }  

3.测试案例1

 

我们的线程池只允许一个线程同时执行,这样的结果是:打印number的值是从1-10顺序打印

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 
  2.  * $filename: TestMain.java,v $ 
  3.  * $Date: 2013-11-20  $ 
  4.  * Copyright (C) ZhengHaibo, Inc. All rights reserved. 
  5.  * This software is Made by Zhenghaibo. 
  6.  */  
  7. package edu.njupt.zhb;  
  8.   
  9. import java.util.ArrayList;  
  10. import java.util.List;  
  11. /* 
  12.  *@author: ZhengHaibo   
  13.  *web:     http://blog.csdn.net/nuptboyzhb 
  14.  *mail:    zhb931706659@126.com 
  15.  *2013-11-20  Nanjing,njupt,China 
  16.  */  
  17. public class TestMain {  
  18.   
  19.     /** 
  20.      * @param args 
  21.      */  
  22.     public static void main(String[] args) {  
  23.         // TODO Auto-generated method stub  
  24.         WorkQueue workQueue = new WorkQueue(1);//只允许同时运行1个线程  
  25.         for (int i = 0; i < 10; i++) {  
  26.             WorkThread wThread = new WorkThread();  
  27.             workQueue.execute(wThread);  
  28.         }  
  29.     }  
  30.   
  31. }  

运行结果是:

 

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. number = 1  
  2. number = 2  
  3. number = 3  
  4. number = 4  
  5. number = 5  
  6. number = 6  
  7. number = 7  
  8. number = 8  
  9. number = 9  
  10. number = 10  

4.测试案例2 

 

线程池中允许同时最多有5个线程一起执行

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 
  2.  * $filename: TestMain.java,v $ 
  3.  * $Date: 2013-11-20  $ 
  4.  * Copyright (C) ZhengHaibo, Inc. All rights reserved. 
  5.  * This software is Made by Zhenghaibo. 
  6.  */  
  7. package edu.njupt.zhb;  
  8.   
  9. import java.util.ArrayList;  
  10. import java.util.List;  
  11. /* 
  12.  *@author: ZhengHaibo   
  13.  *web:     http://blog.csdn.net/nuptboyzhb 
  14.  *mail:    zhb931706659@126.com 
  15.  *2013-11-20  Nanjing,njupt,China 
  16.  */  
  17. public class TestMain {  
  18.   
  19.     /** 
  20.      * @param args 
  21.      */  
  22.     public static void main(String[] args) {  
  23.         // TODO Auto-generated method stub  
  24.         WorkQueue wQueue = new WorkQueue(5);//允许同时运行5个线程  
  25.         for (int i = 0; i < 10; i++) {  
  26.             WorkThread wThread = new WorkThread();  
  27.             wQueue.execute(wThread);  
  28.         }  
  29.     }  
  30.   
  31. }  

运行结果是:

 

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. number = 5  
  2. number = 5  
  3. number = 5  
  4. number = 5  
  5. number = 5  
  6. number = 10  
  7. number = 10  
  8. number = 10  
  9. number = 10  
  10. number = 10  

在某些场合中,如果能够承受100个线程同时运行,那么我们就将workqueue线程池的大小设成100,当线程超过100时,就将线程放入队列queue中,等有一些线程执行结束后,依次执行队列中的线程,一直执行到对列为空时,线程池中的100个线程都在等待新的任务加入。

 

 

未经允许不得用于商业目的

目录
相关文章
|
14天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
68 17
|
11天前
|
存储 监控 Java
JAVA线程池有哪些队列? 以及它们的适用场景案例
不同的线程池队列有着各自的特点和适用场景,在实际使用线程池时,需要根据具体的业务需求、系统资源状况以及对任务执行顺序、响应时间等方面的要求,合理选择相应的队列来构建线程池,以实现高效的任务处理。
88 12
|
24天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
10天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题
|
26天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
26天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
27天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
53 3
|
27天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
146 2
|
1月前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
51 6
|
24天前
|
安全 Java 容器
【JaveEE】——多线程中使用顺序表,队列,哈希表
多线程环境下使用ArrayList(同步机制,写时拷贝),使用队列,哈希表(高频)ConcurrentHashMap(缩小锁粒度,CAS,扩容优化)