Notas de estudio de JAVA (multiproceso 2) - creación de multiproceso (2) (el grupo de subprocesos es muy importante)
Método agregado 1: implementar la interfaz invocable
- En comparación con el uso de Runnable, Callable es más potente. En comparación con el método run(), puede tener un valor de retorno (anulando call()). El método puede generar excepciones y admitir valores de retorno genéricos .
- Debe utilizar la clase FutureTask , como la interfaz Future, para obtener el resultado devuelto.
Descripción de la interfaz futura:- FutrueTask es la única clase de implementación de la interfaz Futrue
- FutureTask también implementa las interfaces Runnable y Future. Puede ser ejecutado por un subproceso como Runnable, y también puede usarse como Future para obtener el valor de retorno de Callable
- La interfaz Future (FutureTask) puede cancelar los resultados de ejecución de tareas Runnable y Callable específicas, consultar si se completaron, obtener resultados, etc.
//1.创建一个实现Callzble的实现类
class NumberThread implements Callable{
//2.重写call方法,将此线程需要执行的操作声明在call()中
@Override
public synchronized Object call() throws Exception {
int sum=0;
for (int i = 0; i <=100 ; i++) {
System.out.println(i);
sum+=i;
}
return sum;
}
}
public class MannyThread {
public static void main(String[] args) {
//3创建CaLLable接口实现类的对象
NumberThread numberThread=new NumberThread();
//4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
FutureTask futureTask=new FutureTask(numberThread);
//5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
Thread thread=new Thread(futureTask);
thread.start();
Object sum= null;
try {
//get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。
sum = futureTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("总和"+sum);
}
}
Método agregado 2: usar grupo de subprocesos (esto también se usa comúnmente en desarrollo)
Antecedentes : los recursos que se crean y destruyen con frecuencia y que utilizan una gran cantidad de recursos, como subprocesos en situaciones simultáneas, tienen un gran impacto en el rendimiento.
Idea : cree varios subprocesos por adelantado, colóquelos en el grupo de subprocesos, obténgalos directamente cuando los use y vuelva a colocarlos en el grupo después de usarlos. Puede evitar la creación y destrucción frecuentes y lograr la reutilización. Similar al transporte público en la vida.
Beneficios del grupo de subprocesos:
- Capacidad de respuesta mejorada (tiempo reducido para crear nuevos hilos)
- Reducir el consumo de recursos (reutilizar subprocesos en el grupo de subprocesos, no es necesario crear cada vez
- Fácil gestión de hilos
Algunos métodos relacionados con el grupo de subprocesos:
- corePoolSize: el tamaño del grupo principal
- MaximumPoolSize: número máximo de subprocesos
- keepAliveTime: cuando el subproceso no tiene tareas, se terminará después de cuánto tiempo se mantendrá como máximo
- …
API relacionada con el grupo de subprocesos :
JDK 5.0 proporciona una API relacionada con el grupo de subprocesos: ExecutorService y Executors
ExecutorsService: la interfaz del grupo de subprocesos reales. Subclase común ThreadPoolExecutor
- ejecución nula (comando ejecutable): ejecutar tarea/comando, sin valor de retorno, generalmente utilizado para ejecutar ejecutable
- Envío futuro (tarea invocable): ejecuta la tarea, tiene un valor de retorno y, en general, ejecuta la invocable
- void shutdown(): cerrar el grupo de conexiones
Ejecutores: clase de herramienta, clase de fábrica de grupos de subprocesos, utilizada para crear y devolver diferentes tipos de grupos de subprocesos
- Executors.newCachedThreadPool(): cree un grupo de subprocesos que pueda crear nuevos subprocesos según sea necesario
- Executors.newFixedThreadPool(n); Crear un grupo de subprocesos con un número fijo de subprocesos reutilizables
- Executors.newSingleThreadExecutor (): crea un grupo de subprocesos con un solo subproceso
- Executors.newScheduledThreadPool(n): crea un grupo de subprocesos que se puede programar para ejecutar comandos después de un retraso determinado o periódicamente.
El uso específico del grupo de subprocesos:
-
Proporcione un grupo de subprocesos con el número especificado de subprocesos x
ExecutorService service= Executors.newFixedThreadPool(x); -
Para ejecutar la operación de subproceso especificada, debe proporcionar un objeto de clase de implementación que implemente la interfaz Runnable o la interfaz Callable
service.execute(new x);//Applicable to Runnable
service.submit();//Applicable to Callable
Note :
service.getClass()= ThreadPoolExecutor,
ThreadPoolExecutor service1=(ThreadPoolExecutor) servicio,
llame al método de grupo de subprocesos a través de service1 para cambiar los atributos; -
Cierre el grupo de subprocesos
service.shutdown();
Ejemplo: Cree dos subprocesos que devuelvan números pares e impares dentro de cien
class NumThread implements Runnable{
@Override
public void run() {
for (int i = 0; i <=100; i++) {
if (i%2==0) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
class NumThread1 implements Runnable{
@Override
public void run() {
for (int i = 0; i <=100; i++) {
if (i%2!=0) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
public class ManyThread2 {
public static void main(String[] args) {
//1.提供指定线程数量的线程池
ExecutorService service= Executors.newFixedThreadPool(10);
//设置线程池的属性
System.out.println(service.getClass());//返回service的类的类型
ThreadPoolExecutor service1=(ThreadPoolExecutor) service;
service1.setCorePoolSize(15);//现在就可以(通过方法)设置属性了
//2.执行指定的线程操作,需要提供实现Runnable接口或Callable接口的实现类对象
service.execute(new NumThread());//适用于Runnable
service.execute(new NumThread1());//适用于Runnable
//service.submit();//适用于Callable
//3.关闭线程池
service.shutdown();
}
}