Executor

简答的一个例子:


服务端:

package com.jerry.concurrency.executor;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;

public class MyServer {

	private static final ExecutorService exec = Executors.newFixedThreadPool(10);
	
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(8080);
		while(!exec.isShutdown()){
			final Socket conn = server.accept();
			Runnable command = new Runnable(){
				@Override
				public void run() {
					Long i = Thread.currentThread().getId();
					System.out.println(i);
					try {
						stop();
					} catch (RejectedExecutionException e) {
						System.out.println("拒绝提交任务!");
					} 
				}
				
			};
			exec.execute(command);
		}		
	}
	
	public static void stop(){
		exec.shutdown();
	}
}


客户端:

package com.jerry.concurrency.executor;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;

public class Cilent {
	
	public static void main(String[] args) throws UnknownHostException, IOException {
		for(int i=0;i<=100;i++){
			Socket socket=new Socket("127.0.0.1",8080);
		}		
	}

}


运行结果可见共创建了10个线程,即使客户端和服务端进行了100次连接。

下面详解一下Executors的静态方法:

newFixedThreadPool 创建一个定长的线程池,每提交一个任务就会创建一个线程,直到最大长度,这时线程池会保持长度不能变化,如果有一个线程由于异常结束,线程池会补充一个新的。

newCachedThreadPool 创建一个可缓存的线程池,可以灵活回收空闲的线程,也可以灵活的添加,并不对池长度做任何限制。

newSingleThreadExecutor 创建一个单线程化的executor,确保只创建一个唯一的线程来执行任务,如果这个线程意外退出了,会有另外一个来取代它。保证任务队列FIFO、LIFO执行。

newScheduledThreadPool 创建一个定长的线程池,支持定时、周期性的任务执行,类似Timer。


ExecutorService扩展了Executor并添加了一些生命周期管理的方法。一个Executor的生命周期有三种状态:运行 ,关闭 ,终止 。Executor创建时处于运行状态。当调用ExecutorService.shutdown()后,处于关闭状态,isShutdown()方法返回true。这时,不应该再想Executor中添加任务,所有已添加的任务执行完毕后,Executor处于终止状态,isTerminated()返回true。shutdownNow()提供强行关闭的过程:取消所有运行中的任务和排在队列中尚未开始的任务。
如果Executor处于关闭状态,往Executor提交任务会抛出unchecked exception RejectedExecutionException。

上面的例子改为一个简单的可以控制生命周期的例子:

package com.jerry.concurrency.executor;


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;


public class MyServer {


private static final ExecutorService exec = Executors.newFixedThreadPool(10);

public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8080);
while(!exec.isShutdown()){
final Socket conn = server.accept();
Runnable command = new Runnable(){
@Override
public void run() {
Long i = Thread.currentThread().getId();
System.out.println(i);
try {
stop();
} catch (RejectedExecutionException e) {
System.out.println("拒绝提交任务!");
} 
}

};
exec.execute(command);
} 
}

public static void stop(){
exec.shutdown();
}
}


客户端代码不变。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Executor框架是Java中的一个重要概念,它主要用于异步执行任务。这个框架的主要功能是将任务的提交与任务的执行分离开来,提供了线程池、延迟和定时执行等功能。 Executor框架的主要组成部分包括以下几个接口和类: 1. Executor:这是最基本的执行器接口,它定义了一个方法execute(Runnable command),用于执行给定的任务。 2. ExecutorService:这是Executor接口的子接口,它增加了一些管理终止和产生Future的方法。 3. ThreadPoolExecutor:这是ExecutorService接口的一个实现,它创建了一个线程池来执行任务。 4. ScheduledExecutorService:这是ExecutorService接口的一个子接口,它支持定期或延迟执行任务。 5. Executors:这是一个工具类,它提供了一些工厂方法,用于创建各种类型的执行器。 6. Future和Callable:Future是一个接口,代表一个异步计算的结果。Callable是一个接口,它的call()方法返回一个结果,并且可以抛出异常。 7. FutureTask:这是一个类,它是Runnable和Future接口的实现,它可以包装Callable或者Runnable对象。 使用Executor框架的好处主要有以下几点: 1. 提高性能:通过重复利用已存在的线程来降低线程创建和销毁造成的开销。 2. 提高响应性:当命令到达时,线程可以立即运行,而不用等待其他线程。 3. 提高线程的可管理性:可以根据需要对线程进行调度、优先级设置等操作。 在使用时,需要注意以下几点: 1. 合理选择线程池的大小:过大的线程池会占用过多的系统资源,过小的线程池则无法充分利用多核CPU的优势。 2. 注意线程安全:在使用多线程时,需要注意数据的同步问题,避免出现数据不一致的情况。 3. 正确处理异常:在异步任务中,如果发生异常,需要有合适的机制进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值