如何创建 n 个线程并使用它们
How to create n threads and work with all of them
我正在尝试创建给定数量的线程并同时处理它们以制作“竞赛”程序。线程已创建,但我做错了什么,因为任何线程都打印“Hi”。
public class Principal implements Runnable{
public static void main(String[] args) {
int howManyThreads = 3;
Thread thread[];
thread = new Thread[howManyThreads];
for ( int i=0; i < thread.length; i++ ){
thread[i]= new Thread();
thread[i].setName("Thread - " + i);
}
for ( int i=0; i < thread.length; ++i){
thread[i].start();
System.out.println(thread[i].getName() + " - " + thread[i].getState());
}
}
public void run() {
System.out.println("Hi");
}
}
Thread
class 的默认构造函数创建一个什么也不做的线程。您在这里调用默认构造函数:thread[i] = new Thread();
如果您希望线程实际执行某些操作,则必须提供一个 Runnable
实例作为 Thread 构造函数的参数。有几种方法可以做到这一点。最新、最简洁的方法是使用 lambda 表达式:
thread[i] = new Thread(() -> {
System.out.println("Hi");
});
Runnable
接口是一个 @FunctionalInterface
。由于编译器知道 Thread(...)
构造函数需要该类型的对象,因此它推断这就是 lambda 应该创建的对象,并且 lambda 的主体成为新对象的 run()
方法。
另一种提供 Runnable
对象的旧方法是使用 匿名内部 class 表达式。语法有点麻烦,因为你必须明确地说出新的 class 应该实现什么接口,并且你必须明确声明 run()
方法:
thread[i] = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hi");
}
});
最古老的方法,甚至更冗长,是显式声明一个命名的 class:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Hi");
}
};
public class Principal /*does not need to implement Runnable*/ {
...
thread[i] = new Thread(new MyRunnable());
...
}
您可能会问,为什么我要从 Principal
class 中删除 implements Runnable
,然后创建一个全新的 class?
我这样做是因为,我读过这本书:https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/
我正在尝试创建给定数量的线程并同时处理它们以制作“竞赛”程序。线程已创建,但我做错了什么,因为任何线程都打印“Hi”。
public class Principal implements Runnable{
public static void main(String[] args) {
int howManyThreads = 3;
Thread thread[];
thread = new Thread[howManyThreads];
for ( int i=0; i < thread.length; i++ ){
thread[i]= new Thread();
thread[i].setName("Thread - " + i);
}
for ( int i=0; i < thread.length; ++i){
thread[i].start();
System.out.println(thread[i].getName() + " - " + thread[i].getState());
}
}
public void run() {
System.out.println("Hi");
}
}
Thread
class 的默认构造函数创建一个什么也不做的线程。您在这里调用默认构造函数:thread[i] = new Thread();
如果您希望线程实际执行某些操作,则必须提供一个 Runnable
实例作为 Thread 构造函数的参数。有几种方法可以做到这一点。最新、最简洁的方法是使用 lambda 表达式:
thread[i] = new Thread(() -> {
System.out.println("Hi");
});
Runnable
接口是一个 @FunctionalInterface
。由于编译器知道 Thread(...)
构造函数需要该类型的对象,因此它推断这就是 lambda 应该创建的对象,并且 lambda 的主体成为新对象的 run()
方法。
另一种提供 Runnable
对象的旧方法是使用 匿名内部 class 表达式。语法有点麻烦,因为你必须明确地说出新的 class 应该实现什么接口,并且你必须明确声明 run()
方法:
thread[i] = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hi");
}
});
最古老的方法,甚至更冗长,是显式声明一个命名的 class:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Hi");
}
};
public class Principal /*does not need to implement Runnable*/ {
...
thread[i] = new Thread(new MyRunnable());
...
}
您可能会问,为什么我要从 Principal
class 中删除 implements Runnable
,然后创建一个全新的 class?
我这样做是因为,我读过这本书:https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/