Java 多线程的实现
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
1. 继承Thread类
java.lang.Thread是一个线程操作的核心类。新建一个线程最简单的方法就是直接继承Thread类,而后覆写该类中的run()方法(就相当于主类中的main方法)
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);
}
}
}
当现在有了线程的主体类之后,很自然我们就会想到产生线程类的实例化对象而后调用run()方法。实际上,我们不能够直接去调用run()方法。因为这个时候只是做了一个顺序打印,和多线程一点关系都没有。正确启动多线程的方式是调用Thread类中的start()方
法。
启动多线程:public synchronized void start()此方法会自动调用线程的run()方法
如下所示:正确启动线程的方式
public class TestDemo {
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();
}
}
2. Runnable()接口实现多线程
Thread类的核心功能是进行线程的启动。如果一个类为了实现多线程直接去继承Thread类就会有单继承局限。在java中又提供有另外一种实现模式:Runnable接口。
class MyThread implements Runnable { // 线程主体类
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);
}
}
}
这样写以后,新的问题就产生了。此时MyThread类继承的不再是Thread类而实现了Runnable接口,虽然解决了单继承局限问题,但是没有start()方法被继承了。那么此时就需要关注Thread类提供的构造方法。
Thread类提供的构造方法:
public Thread(Runnable target)
可以接收Runnable接口对象。
启动线程:
public class TestDemo {
public static void main(String[] args) {
MyThread myThread1 = new MyThread("thread1") ;
MyThread myThread2 = new MyThread("thread2") ;
MyThread myThread3 = new MyThread("thread3") ;
new Thread(myThread1).start();
new Thread(myThread2).start();
new Thread(myThread3).start();
}
}
这个时候就启动了多线程。多线程的启动永远都是Thread类的start()方法。
3.Callable实现多线程
从JDK1.5开始追加了新的开发包:java.uti.concurrent。这个开发包主要是进行高并发编程使用的,包含很多在高并发操作中会使用的类。在这个包里定义有一个新的接口Callable。
Runnable中的run()方法没有返回值,它的设计也遵循了主方法的设计原则:线程开始了就别回头。但是很多时候需要一些返回值,例如某些线程执行完成后可能带来一些返回结果,这种情况下就只能利用Callable来实现多线程。
Callable的继承树:
class MyThread implements Callable<String> {
private int ticket = 10 ; // 一共10张票
@Override
public String call() throws Exception {
while(this.ticket>0){
System.out.println("剩余票数:"+this.ticket -- );
}
return "票卖完了,下次吧。。。" ;
}
}
public class TestDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> task = new FutureTask<>(new MyThread()) ;
new Thread(task).start();
new Thread(task).start();
System.out.println(task.get());
}
}