继承Thread类实现多线程
Java.lang.Thread是线程操作的核心类,新建一个线程最简单的方法就是直接继承Thread类,而后覆写run()方法。
//继承Thread类实现多线程
//线程主体类
class MyThread extends Thread{
private String title;
public MyThread(String title) {
this.title = title;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
System.out.println(this.title+",i="+i);
}
}
}
public class Test {
public static void main(String[] args) {
MyThread myThread1 = new MyThread("Thread1");
MyThread myThread2 = new MyThread("Thread2");
MyThread myThread3 = new MyThread("Thread3");
myThread1.start();
myThread2.start();
myThread3.start();
}
}
实现Runnable接口实现多线程
启动一个线程就要调用start()方法,但是Runnable接口中没有start()方法,该怎么办呢?
实际上,虽然Runnable接口中没有start()方法,但是start()方法在Thread类中,并且Thread类实现了Runnable接口,所以我们可以通过向Thread类的构造方法中传一个Runnable接口对象来调用start()方法,启动多线程。
//Runnable接口实现多线程
//class Thread implements Runnable 所以 public Thread(Runnable target) 可以接收Runnable接口对象
//利用Runnable接口实现线程主体类
class MyThread1 implements Runnable{
private String title;
public MyThread1(String title) {
this.title = title;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
System.out.println(this.title+",i="+i);
}
}
}
//启动多线程
public class Test1 {
public static void main(String[] args) {
MyThread1 myThread1a = new MyThread1("myThread1a");//Runnable接口对象
MyThread1 myThread1b = new MyThread1("myThread1b");
MyThread1 myThread1c = new MyThread1("myThread1c");
//Thread 匿名内部类
new Thread(myThread1a).start();
new Thread(myThread1b).start();
new Thread(myThread1c).start();
}
}
实现Callable接口实现多线程
Java.util.concurrent.Callable是JDK1.5新增的高并发程序编程包。
要实现多线程,首先要实现Callable,然后覆写call()方法,接口的返回值用Future接口的get()方法来接收。
//Callable实现多线程
//使用Callable定义线程主体类
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyThread5 implements Callable<String>{
private int ticket = 10;
@Override
public String call() {
while(this.ticket > 0){
System.out.println("剩余票数"+this.ticket--);
}
return "票卖完了";
}
}
/*
要把一个Callable对象启动,核心类是FutureTask,它既是Runnable的子类也是Future的子类,但是它能传进来一个
Callable的对象,所以FutureTask这个类打通了Thread类和MyThread类
*/
public class Test5 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> task = new FutureTask<>(new MyThread5());
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
System.out.println(task.get());
}
}
注意:
无论那种方式实现多线程,程序启动一定调用的是Thread类的start()方法!!!
一个线程的start()方法只能调用一次,多次调用报java.lang.IllegalThreadstateException错误。
分析:
Thread类实现多线程与实现Runnable接口实现多线程都要覆写run()方法,二者有何关系呢?
第一点就是Thread类与自定义线程类(实现了Runnable接口),是一个典型的代理设计模式,Thread类负责辅助真实业务操作(资源调度,创建线程并启动),自定义线程类负责真实业务的实现。
第二点使用Runnable接口实现的多线程程序可以更好地描述共享的概念。
第三点Thread类有单继承的缺点,Runnable接口可以多实现。