Java中实现多线程的方式有下面三种:java
package fs; public class ThreadTest { public static void main(String[] args) { new MyThread().start(); } } class MyThread extends Thread { @Override public void run() { System.out.println("我是一个线程,我叫:"+Thread.currentThread().getName()); } }
package fs; public class ThreadTest { public static void main(String[] args) { new Thread(new MyRunnable()).start(); } } class MyRunnable implements Runnable { @Override public void run() { System.out.println("我是一个线程,我叫:"+Thread.currentThread().getName()); } }
package fs; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { MyCallable call = new MyCallable(); FutureTask<String> task = new FutureTask<String>(call); new Thread(task).start(); String result = task.get(); System.out.println(result); } } class MyCallable implements Callable<String> { @Override public String call() throws Exception { return "Hello"; } }
上面的三种方式的区别在哪呢?面试
实现方式不一样
第一种是继承的方式,第二种和第三种都是实现接口的方式微信
返回值
第一种和第二种有一个共同的特色就是没有返回值,而第三种是有返回值的多线程
扩展性
在Java中咱们都知道类只能单继承,若是咱们本身建立的线程类是经过继承Thread类的方法来实现的,那么这个自定义类就不能再去扩展其余的类,也就是说不能再去实现更加复杂的功能。
若是咱们用实现Runnable接口的方式来建立线程类,这样就能够避免Java单继承所带来的局限性,经过接口多实现的特性进行扩展。并发
下面经过一段简单的代码来进行讲解ide
定义一个售票窗口类线程
class TicketWindow extends Thread { int count = 100; @Override public void run() { System.out.println("窗口:"+Thread.currentThread().getName() + ":卖票啦" + count--); } } public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { for (int i = 0; i < 5; i++) { TicketWindow t = new TicketWindow(); t.start(); } } }
执行结果以下:code
窗口:Thread-1:卖票啦100 窗口:Thread-0:卖票啦100 窗口:Thread-2:卖票啦100 窗口:Thread-3:卖票啦100 窗口:Thread-4:卖票啦100
每一个线程都有本身的票总量,处理的都是本身的票,就是说每一个窗口各自卖各自的票,这就是继承实现线程的特色,一个线程处理一件事情blog
下面来看接口实现方式的代码继承
class TicketWindow2 implements Runnable { int count = 100; @Override public void run() { System.out.println("窗口2:"+Thread.currentThread().getName() + ":卖票啦" + count--); } } public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { TicketWindow2 t2 = new TicketWindow2(); for (int i = 0; i < 5; i++) { new Thread(t2).start(); } } }
执行结果以下:
窗口2:Thread-0:卖票啦100 窗口2:Thread-3:卖票啦97 窗口2:Thread-1:卖票啦99 窗口2:Thread-2:卖票啦98 窗口2:Thread-4:卖票啦96
总共5个窗口也就是5个线程,执行的业务逻辑是相同的,至关于卖的是共享的票,我卖完了,你那边就不能卖了,实际上也是这样的,咱们在12306买票就是这个逻辑,固然这边没有考虑到并发下票数超卖的状况。接口实现的方式可让多个线程作同一件事情。
推荐相关阅读:
《注解面试题-请了解下》