1.继承Thread
1)实现一个单独类
创建一个类MyThraed类,让这个类继承Thread,MyThread中需要重写run方法,代码如下 :
class MyThread extends Thread{
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}
public class CreateThread1 {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
2)使用匿名内部类
public class CreateThread2 {
public static void main(String[] args) {
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
};
thread.start();
}
}
2.实现Runnable接口
1)实现一个单独类
自己创建一个单独类MyThread,让MyThread实现Runnable接口,再重写run方法,在将MyThread作为参数传入Thread的构造方法中,代码如下:
class MyThread implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}
public class CreateThread3 {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
}
}
2)使用匿名内部类
public class CreateThread4 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
3.使用lambda表达式
在创建Thread对象时使用lambda表达式,代码如下:
public class CreateThread5 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
});
thread.start();
}
}
4.实现Callable接口
public class CreateThread6 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
};
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(futureTask.get());
}
}
当我们实现了Callable接口后,由于Thread的构造方法不能直接传入callable对象,于是需要使用FutuerTask过度一下,将callable对象传入 FutureTask中,再将futureTask对象传入Thread中,就完成了线程的创建过程。
需要注意的是,Callable的泛型参数、call的返回值类型和FutureTask的泛型参数需要相同。
由于Thread本身不提供获取返回值的方法,于是就需要使用FutureTask中的get方法来获取call的返回值,在call的结果计算出来之前,其他线程就会产生阻塞,包括main线程。
5.使用线程池或线程工厂
class MyThread implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}
public class CreateThread7 {
public static void main(String[] args) {
MyThread myThread = new MyThread();
//创建含有4个核心线程的线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 4; i++) {
//向线程池中提交任务
executorService.submit(myThread);
}
//关闭线程池
executorService.shutdown();
}
}