1 继承 Thread类
(1) 自定义的线程类继承Thread然后 重写 run() 方法
(2) 使用时new 一个自定义的线程类的对象,然后调用start() 方法
public class MyThread extends Thread {
@Override
public void run(){
for (int i = 0; i <10 ; i++) {
System.out.println(this.getName()+": " +System.currentTimeMillis());
}
}
}
public class MainThread {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
2 实现 Runnable接口
(1) 自定义一个类继承Runnable接口 然后实现 run()方法
(2) 分别 new 一个该类的对象和一个Thread类的对象 把自定义类的对象当参数传入Thread的构造方法中
(Thread 构造方法也支持2个参数,第二个参数为线程名称)
(3) 使用时 调用Thread对象的start()方法
public class RunnableThread implements Runnable {
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println( +System.currentTimeMillis());
}
}
}
public class MainThread {
public static void main(String[] args) {
Thread thread=new Thread(new RunnableThread(),"runableThread");
thread.start();
}
}
3 实现 Callable接口
(1) 创建一个自定义的类MyCallable 实现Callable接口(实现Callable接口时要传一个泛型,该泛型就是你call方法的返回值型)
并重写call()方法,call()方法是有返回值的! call方法中的内容就是 你自己要执行的代码。
(2) 使用时先创建一个 MyCallable 对象,然后在创建一个FutureTask对象(创建FutureTask对象要传一个泛型, 该泛型与call方法的
返回值类型保持一致)将MyCallable 对象传入,最后再创建一个Thread对象将FutureTask对象传入,调用thread.start()
public class MyCallable implements Callable<String> {
public String call() {
System.out.println(System.currentTimeMillis());
return "OK";
}
}
public class StartApplication {
public static void main(String[] args) {
FutureTask<String> futureTask=new FutureTask<String>(new MyCallable());
Thread thread=new Thread(futureTask,"myThread");
thread.start();
}
}
4 通过线程池创建线程
(1) 自定义一个类继承Runnable接口 然后实现 run()方法
(2) 通过Executors获取线程池对象,并执行execute()方法
public class RunnableThread implements Runnable {
public void run() {
for (int i = 0; i <10 ; i++) {
System.out.println( +System.currentTimeMillis());
}
}
}
public class MainThread {
public static void main(String[] args) {
RunnableThread runnableThread=new RunnableThread();
//固定数量的线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(runnableThread);
}
}
5 总结(各种方法的对比)
1. 实现Runnab接口/继承Thread类
(1) 接口更适合多个相同的程序代码的线程共享同一个资源
(2) 接口避免了单继承的局限性
(3)接口代码可以被多个线程共享。代码和线程独立
(4) 线程池只能放入实现runnable接口或callable接口的线程,不能直接让如Thread的子类
java中最少启动2个线程 一个main 一个垃圾回收线程
2. 实现Runna接口/实现Callable接口
-
相同点
(1) 都是实现接口
(2) 都可编写多线程
(3) 都需要调用Thread.start() -
不同点
(1) 实现callable接口有返回值
(2) callable的 call() 方法可抛异常
(3)callable 可调用Future.cancel方法取消