java线程池创建ThreadPoolTaskExecutor和Executors

  • Post author:
  • Post category:java



一.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;
	}
}



版权声明:本文为weixin_37460672原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。