java线程池创建ThreadPoolTaskExecutor和Executors

无情 阅读:685 2021-04-01 11:16:52 评论:0

一.ThreadPoolTaskExecutor创建方式
1.注入线程池对象五个参数,面试常问

<bean id="taskExcetor" 
		class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
		<property name="corePoolSize" value="10" /> 
		<property name="keepAliveSeconds" value="200" /> 
		<property name="maxPoolSize" value="20" /> 
		<property name="queueCapacity" value="20" /> 
		<property name="rejectedExecutionHandler"> 
			<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> 
		</property> 
	</bean> 

属性字段说明
corePoolSize:线程池维护线程的最少数量
keepAliveSeconds:允许的空闲时间
maxPoolSize:线程池维护线程的最大数量
queueCapacity:缓存队列
rejectedExecutionHandler:对拒绝task的处理策略
2.execute方法执行过程
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maxPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maxPoolSize,那么通过handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
3.代码中调用线程池,异步处理日志

	@Autowired 
	private ThreadPoolTaskExecutor taskExcetor; 
	@GetMapping("test") 
	public void test(){ 
	taskExcetor.execute(new Runnable() { 
			@Override 
			public void run() { 
				RobotVoiceInfoEntity robotVoiceInfo = new RobotVoiceInfoEntity(); 
				robotVoiceInfo.setCreateTime(new Date()); 
				robotVoiceInfo.setInset(inset); 
				robotVoiceInfo.setRobotName(robotName); 
				robotVoiceInfo.setText(text); 
				robotVoiceInfoService.save(robotVoiceInfo); 
			} 
		}); 
	} 

二.Executors创建线程池
1.创建线程池

@Component 
public class SocketServer { 
	public static Map<String, Socket> map = new ConcurrentHashMap<String, Socket>(); 
	@PostConstruct 
	public void acceptData() { 
		new Thread(new Runnable() { 
			@Override 
			public void run() { 
				ExecutorService pool = Executors.newFixedThreadPool(50); 
				try(ServerSocket serverSocket = new ServerSocket(Integer.parseInt(port))) { 
					while(true) { 
						Socket socket = serverSocket.accept(); 
						String ip = socket.getInetAddress().toString(); 
						map.put(ip,socket); 
						Callable<Void> task = new SocketCallable(socket,ip); 
						pool.submit(task); 
					} 
				}catch(BindException e) { 
					e.printStackTrace(); 
				}catch(IOException e) { 
					e.printStackTrace(); 
				} 
			} 
		}).start(); 
	} 
}	 

2.socket多线程等待客户端链接

	private Logger logger = LoggerFactory.getLogger(this.getClass()); 
	private Socket socket; 
	private String ip; 
	public SocketCallable(Socket socket,String ip) { 
		this.socket = socket; 
		this.ip = ip; 
	} 
	@Override 
	public Void call() { 
		try { 
			InputStream inputStream = socket.getInputStream(); 
			DataInputStream dis = new DataInputStream(inputStream); 
			OutputStream outputStream = socket.getOutputStream(); 
			DataOutputStream dos = new DataOutputStream(outputStream); 
			while(true) { 
				byte[] datas1 = new byte[7]; 
				dis.readFully(datas1); 
				String prefix = Hex2AscUtil.hex2Asc(datas1.length, datas1); 
				String hex = prefix.substring(12); 
				byte[] datas2 = null; 
				if("80".equals(hex)) { 
					datas2 = new byte[8]; 
					dis.readFully(datas2); 
					byte[] reqdata = {(byte) 0x57, 0x4b, 0x4c, 0x59, 0x09, 0x00, (byte) 0x80, 0x00, 0x00}; 
					dos.write(reqdata); 
					dos.flush(); 
					String resp = Hex2AscUtil.hex2Asc(reqdata.length, reqdata); 
				}else{ 
					logger.info("socket解析数据不正确"); 
					continue; 
				} 
			} 
		}catch(Exception e) { 
			e.printStackTrace(); 
		}finally { 
			if(socket != null) 
				try { 
					Socket remove = SocketServer.map.remove(ip); 
					socket.close(); 
				}catch(IOException e1) { 
					e1.printStackTrace(); 
				} 
		} 
		return null; 
	} 
} 
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号