多线程的实现方法主要有三种分别是Thread类,Runnable接口和 callable接口,下面分别来讲述一下三者的不同。
首先是Thread类,需要被继承之后才能实现,在实现的时候需要覆写run()方法,但是在启动的时候要用start()方法启动。
下面是一个卖票的小程序
class MyThread extends Thread { //这是一个多线程的操作类 private int ticket = 10 ; @Override public void run(){ //覆写run()方法,作为线程主体操作方法 for(int x = 0 ;x <100; x ++) { if(this.ticket > 0){ System.out.println("卖票,ticket =" + this.ticket --) ; } } } } public class TestDemo { //主类 public static void main(String [] args){ //由于MyThread类有start()方法,所以每一个MyThread类对象就是一个线程对象,可以直接启动 MyThread mt1 = new MyThread() ; MyThread mt2 = new MyThread() ; MyThread mt3 = new MyThread() ; mt1.start(); mt2.start(); mt3.start(); } }
运行结果
Thread类实线多线程之后没有共享资源,以卖票为例,总共十张票,让三个人去卖,如果每个人都当自己有十张票,那么总共就需要三十张票,这显然不是我们想要的结果。
下面以Runnable接口来实现这个程序
class MyThread implements Runnable { //这是一个多线程的操作类 private int ticket = 10 ; @Override public void run(){ //覆写run()方法,作为线程主体操作方法 for(int x = 0 ;x <100; x ++) { if(this.ticket > 0){ System.out.println("卖票,ticket =" + this.ticket --) ; } } } } public class TestDemo { //主类 public static void main(String [] args){ //由于MyThread类有start()方法,所以每一个MyThread类对象就是一个线程对象,可以直接启动 MyThread mt = new MyThread(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); } }
运行结果
Runnable接口实现多线程就能达到资源共享的情况,同时使用Runnable接口还能避免单继承的局限性。在Thread类中是继承了Runnable接口,所以Runnable的多线程的实现,也是用到了Thread类中的start()方法。
同样callable接口是为了在java 1.5之后出现的,它是为了解决Runnable接口操作完之后不能返回操作结果的缺陷而设计的
import java.util.concurrent.Callable ; import java.util.concurrent.FutureTask ; class MyThread implements Callable<String> { //这是一个多线程的操作类 private int ticket = 10 ; @Override public String call() throws Exception { for(int x = 0 ;x <100; x ++) { if(this.ticket > 0){ System.out.println("卖票,ticket =" + this.ticket --) ; } } return "票已卖光" ; } } public class TestDemo { //主类 public static void main(String [] args) throws Exception { MyThread mt1 = new MyThread(); MyThread mt2 = new MyThread(); FutureTask<String> task1 = new FutureTask(mt1) ;//目的是为了取回call()返回结果 FutureTask<String> task2 = new FutureTask(mt2) ;//目的是为了取回call()返回结果 //FutureTask是Runnable接口子类,所以可以使用Thread类的构造来接收task对象 new Thread(task1).start(); new Thread(task2).start(); //多线程执行完毕后可以取得内容,依靠FutureTask的父接口Future中的get()方法完成 System.out.println("A线程返回的结果:" + task1.get()); System.out.println("B线程返回的结果:" + task1.get()); } }
由于Callable接口实现多线程的方式比较麻烦,所以一般不用此操作,只做了解。