JAVA中建立线程的三种方法及比较

 

  JAVA中建立线程的方式有三种,各有优缺点,具体以下:编程

 

1、继承Thread类来建立线程多线程

一、建立一个任务类,继承Thread线程类,由于Thread类已经实现了Runnable接口,而后重写run()方法,run()方法中的内容就是须要线程完成的任务。this

二、建立一个任务类的对象,即建立了线程对象。spa

三、调用任务类对象的start()方法,来启动一个线程。线程

代码实例:code

 1 public class TestThread extends Thread {
 2     public void run() {
 3         for (int i = 0; i < 20; i++) {
 4             // 与Thread.currentThread().getName()相同
 5             System.out.println(this.getName() + " " + i);
 6         }
 7     }
 8 
 9     public static void main(String[] args) {
10         TestThread t1 = new TestThread();
11         TestThread t2 = new TestThread();
12         t1.start();
13         t2.start();
14     }
15 }

 

2、实现Runnable接口来建立线程对象

一、建立一个任务类,实现Runnable接口,并实现run()方法,run()方法中的内容就是须要线程完成的任务。blog

二、建立一个任务类的对象。继承

三、任务类必须在线程中执行,所以将任务类的对象做为参数,建立一个Thread类对象,该Thread类对象才是真正的线程对象。接口

四、调用Thread线程类对象的start()方法,来启动一个线程。

代码实例:

 1 public class TestThread implements Runnable {
 2     public void run() {
 3         for (int i = 0; i < 20; i++) {
 4             // 获取线程名称,默认格式:Thread-0
 5             System.out.println(Thread.currentThread().getName() + " " + i);
 6         }
 7     }
 8 
 9     public static void main(String[] args) {
10         TestThread tt1 = new TestThread();
11         TestThread tt2 = new TestThread();
12         // 可为线程添加名称:Thread t1 = new Thread(tt1, "线程1");
13         Thread t1 = new Thread(tt1);
14         Thread t2 = new Thread(tt2);
15         t1.start();
16         t2.start();
17     }
18 }

 

3、经过Callable和Future来建立线程

一、建立一个任务类,实现Callable接口,并实现call()方法,call()方法中的内容就是须要线程完成的任务,且有返回值。

二、建立一个任务类的对象,并使用FutureTask类来包装任务类的对象,该FutureTask对象封装了任务类对象中call()方法的返回值。

三、任务类必须在线程中执行,所以将FutureTask类的对象做为参数,建立一个Thread类对象,该Thread类对象才是真正的线程对象。

四、调用Thread线程类对象的start()方法,来启动一个线程。

五、调用FutureTask类对象的get()方法来获取线程执行的返回值,即任务类对象中call()方法的返回值。

代码实例:

 1 public class TestThread implements Callable<Integer> {
 2     public Integer call() {
 3         int i = 0;
 4         for (i = 0; i < 20; i++) {
 5             if (i == 5)
 6                 break;
 7             System.out.println(Thread.currentThread().getName() + " " + i);
 8         }
 9         return i;
10     }
11 
12     public static void main(String[] args) {
13         TestThread tt = new TestThread();
14         FutureTask<Integer> ft = new FutureTask<Integer>(tt);
15         Thread t = new Thread(ft);
16         t.start();
17         try {
18             System.out.println(Thread.currentThread().getName() + " " + ft.get());
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 }

 

4、三种方式建立线程的比较

一、继承Thread类方式:

(1)优势:编写简单,任务类中访问当前线程时,能够直接使用this关键字。

(2)缺点:任务类即线程类已经继承了Thread类,因此不能再继承其余父类。

二、实现Runnable接口的方式:

(1)优势:任务类只实现了Runnable接口,还能够继承其余类。这种方式,能够多个线程对象共享一个任务类对象,即多线程共享一份资源的状况,以下:

1     TestThread tt1 = new TestThread();
2     Thread t1 = new Thread(tt1);
3     Thread t2 = new Thread(tt1);
4     t1.start();
5     t2.start();

(2)缺点:编写稍微复杂,任务类中访问当前线程时,必须使用Thread.currentThread()方法。

三、经过Callable和Future的方式:

(1)优势:任务类只实现了Callable接口,还能够继承其余类,一样多线程下可共享同一份资源,这种方式还有返回值,而且能够抛出返回值的异常。

(2)缺点:编写稍微复杂,任务类中访问当前线程时,必须使用Thread.currentThread()方法。

 

  总结:在仅仅只重写run()方法,而不重写Thread类其余方法的前提下,比较推荐实现Runnable接口的方式建立线程。由于不打算修改或加强类的基本能力,不该该为其建立子类。并且实现Runnable接口的方式,线程和资源相对分离,程序更加健壮,更符合面向对象的编程思想。固然,须要线程有返回值时能够使用Callable的方式,但Callable的方式有一个问题,当调用get()方法时,若是线程还未执行完毕,则会阻塞到线程执行完毕拿到返回值。

相关文章
相关标签/搜索