1、继承 Thread 类
public class ThreadTest extends Thread{
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("自定义线程执行了"+i+"次");
}
}
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
//run方法是自定义类的一个普通方法,调用就会直接执行
threadTest.run();
//调用start方法会开启线程,当这个线程得到cpu分配的时间片时,线程才会执行
threadTest.start();
for (int i = 0; i < 200; i++) {
System.out.println("主线程执行了"+i+"次");
}
}
}
总结:run方法和start方法的区别是,调用run方法线程会直接执行,调用start方法时线程不会立即执行,只有得到cpu分配的时间片时才会执行,只有调用start方法才能实现多线程。
2、通过实现 Runnable 接口
public class RunableTest implements Runnable{
public void run() {
for (int i = 0; i < 200; i++) {
//Thread.currentThread().getName()获取当前线程的名字
System.out.println(Thread.currentThread().getName()+"线程执行了"+i+"次");
}
}
public static void main(String[] args) {
RunableTest t1 = new RunableTest();
RunableTest t2 = new RunableTest();
new Thread(t1,"t1").start();
new Thread(t2,"t2").start();
for (int i = 0; i < 200; i++) {
System.out.println("主线程执行了"+i+"次");
}
}
}
通过Thread类调用start方法开启线程,Thread的有参构造,第一个参数代表要开启的线程类,第二个参数是给要开启的线程取的名字。
3、通过 Callable 创建线程。
import java.util.concurrent.*;
public class CallableTest implements Callable<Boolean> {
public Boolean call() throws Exception {
for (int i = 0; i < 200; i++) {
System.out.println(Thread.currentThread().getName()+"线程执行了"+i+"次");
}
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableTest t1 = new CallableTest();
CallableTest t2 = new CallableTest();
CallableTest t3 = new CallableTest();
//创建执行服务
ExecutorService service = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> s1 = service.submit(t1);
Future<Boolean> s2 = service.submit(t2);
Future<Boolean> s3 = service.submit(t3);
//获取结果
Boolean r1 = s1.get();
Boolean r2 = s2.get();
Boolean r3 = s3.get();
//关闭服务
service.shutdown();
}
}
总结:创建多线程常用的方法就是这三种,继承Thread类和实现Runable接口,都是需要重写run方法,而实现Callable接口需要重写call方法。由于Java是单继承的所以,建议在开发中多使用实现Runable接口的方式来创建线程,其实Thread类也是实现了Runable接口。如果需要返回值可以使用Callable接口创建的线程,只有Callable接口提供了返回值,前两种方法没有返回值。