Java 创建线程有三种方式:
(一) 实现Runnable接口
优点:(1) 创建线程的同时可以继承其他的类,从而可以扩展类的功能。
(2) 同一个实现Runnable接口的实例可以作为多个Thread的target,这样可以实现资源的共享。
缺点:相对于继承Thread类,实现Runnable接口代码要繁琐一些
代码实例如下:
- public class ImplementsRunnable implements Runnable{
-
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());
- }
-
- public static void main(String[] args) {
-
-
- System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());
-
-
- ImplementsRunnable runnableTarget = new ImplementsRunnable();
- Thread thread1 = new Thread(runnableTarget,"ThreadName1");
- thread1.start();
-
-
- new Thread(new Runnable() {
- public void run() {
- System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());
- }
- },"ThreadName2").start();
- }
-
- }
- 输出结果:main ThreadId: 1
- ThreadName1 ThreadId: 9
- ThreadName2 ThreadId: 10
(二) 继承Thread 类,重载Thread类的run()方法。事实上Thread类也是实现了Runnable接口。
优点:代码相对其他两种方式更简洁
缺点:由于java的继承机制是单一继承,继承Thread类就不能继承其他的类。
代码实例:
- public class ExtendsThread extends Thread{
-
- public ExtendsThread(String threadName) {
- super(threadName);
- }
-
- public void run() {
- System.out.println("ThreadName: " + getName());
- }
-
- public static void main(String[] args) {
-
-
-
- System.out.println(Thread.currentThread().getName()+" ThreadId: "+ Thread.currentThread().getId());
-
-
- ExtendsThread et = new ExtendsThread("childThread");
- et.start();
-
- }
- }
(三) 实现Callable<V>接口 并实现接口的唯一方法call()
有些场景会希望得到线程的计算结果,这时可以实现Callable<V> 接口。Callable<V>接口和Runnable接口都是封装了一个异步任务,不同的是
Callable<V>接口具有返回值。同时Call<V>接口还是一个参数化的类型,这个参数就是线程的返回参数类型,比如线程若返回整型则Callable<Integer>
,若返回字符类型则为Callable<Object>。
通过实现Callable<V>接口创建线程,需要用到一个包装器FutureTask<V>,这个包装器同时实现了Runnable和Future<V>接口,它可以将Callable<V>
对象转换为Runnable和Future。
- public interface Callable<V> {
-
- V call() throws Exception;
- }
-
- public interface Future<V> {
-
- boolean cancel(boolean mayInterruptIfRunning);
-
- boolean isCancelled();
-
- boolean isDone();
-
- V get() throws InterruptedException, ExecutionException;
-
- V get(long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException;
- }
-
- public interface RunnableFuture<V> extends Runnable, Future<V> {
-
-
-
-
- void run();
- }
-
-
- public class FutureTask<V> implements RunnableFuture<V> {
- ......
- }
代码实例:
- public class ImplemetsCallable implements Callable<Integer>{
-
-
- public Integer call() {
- return 35;
- }
-
- public static void main(String [] args) throws
- InterruptedException, ExecutionException, TimeoutException {
-
- ImplemetsCallable ic = new ImplemetsCallable();
-
- FutureTask<Integer> task = new FutureTask<Integer>(ic);
- Thread t = new Thread(task);
- t.start();
-
-
- System.out.println(task.get());
-
-
-
- System.out.println(task.get(10000, TimeUnit.MILLISECONDS));
- }
-
- }
以下代码是通过使用线程池的方式创建线程:
- public class TestCallable {
-
- public static void main(String[] args) {
-
- System.out.println("程序开始执行");
- List<Future> list = new ArrayList<Future>();
- int taskSize = 5;
-
- ExecutorService pool = Executors.newFixedThreadPool(taskSize);
-
- for (int i = 0; i<taskSize; i++) {
- MyCallable mc = new MyCallable("i "+i);
- Future f = pool.submit(mc);
- list.add(f);
- }
-
- for (Future f : list) {
- try {
- System.out.println(f.get().toString());
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- } catch (ExecutionException e) {
-
- e.printStackTrace();
- }
- }
- }
-
- }
-
- class MyCallable implements Callable<Object> {
-
- private String name;
-
- public MyCallable(String name) {
- this.name = name;
- }
-
- public Object call() {
- System.out.println("任务开始执行>>>>");
- long beginTime = System.currentTimeMillis();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- }
- long endTime = System.currentTimeMillis();
- long durTime = endTime - beginTime;
- System.out.println("任务执行完毕>>>>");
- return name + "任务执行完毕>>>> 总耗时: "+ durTime;
- }
- }