Naturalmente, conocemos las tres formas de crear hilos. No hablaré de las dos primeras. Esta vez hablamos de la tercera interfaz invocable .
Primero, comparemos la diferencia entre la interfaz ejecutable y la interfaz invocable:
//Runnable接口
class MyThreadRunnable implements Runnable {
@Override
public void run() {
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
return 1024;
}
}
Podemos ver que Callable tiene valores genéricos y de retorno. Esta es una mejora de la tecnología antigua original. Debido al valor de retorno, se mejora el subproceso de grano fino.
Luego miramos la forma de crear hilos:
//Runnable
MyThreadRunnable myThread1=new MyThreadRunnable();
Thread t1=new Thread(myThread1);
Pero de esta manera, usamos Callable para crear un hilo, pero se reporta un error. ¿Por qué?
Razón: ¡El hilo no tiene un constructor invocable!
Entonces, ¿cómo creamos hilos? ?
Primero mira la API, mira la interfaz Runable: haz
clic en su clase de implementación y
mira su método de construcción: el
proceso es el siguiente:
lo que podemos ver es que los parámetros requeridos por este constructor son las clases de implementación de la interfaz Callable.
Entonces, la forma en que creamos hilos es la siguiente:
public class CallableDemo {
public static void main(String[] args) {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
System.out.println(futureTask.get());// 1024 通过get方法来获取返回值
}
}
Aquí miramos algunos detalles:
Detalle uno:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
System.out.println(futureTask.get());// 1024 通过get方式来获取返回值 该方法会阻塞!
System.out.println(Thread.currentThread().getName()+"***计算完成");
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
Thread.sleep(5000);
return 1024;
}
}
Luego cambia a la posición
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
System.out.println(Thread.currentThread().getName()+"***计算完成");
System.out.println(futureTask.get());// 1024 通过get方式来获取返回值 该方法会阻塞!
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
Thread.sleep(5000);
return 1024;
}
}
Entonces podemos saber que el método get tiene un efecto de bloqueo.
Detalle 2:
Agregar un nuevo hilo B:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
new Thread(futureTask, "B").start();
System.out.println(Thread.currentThread().getName() + "***计算完成");
System.out.println(futureTask.get());// 1024 通过get方式来获取返回值 该方法会阻塞!
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
Thread.sleep(5000);
return 1024;
}
}
Resultado de impresión:
solo se ejecuta una vez, porque un futureTask, sin importar cuántos subprocesos se llamen, ¡todos llaman al mismo objeto futureTask! Y la interfaz Runnable es diferente:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThreadRunnable t = new MyThreadRunnable();
Thread thread = new Thread(t);
new Thread(thread).run();
new Thread(thread).run();
}
}
//Runnable接口
class MyThreadRunnable implements Runnable {
@Override
public void run() {
System.out.println("******come in here");
}
}
Lo anterior es la forma de crear hilos mediante la implementación de la interfaz invocable.