zoukankan      html  css  js  c++  java
  • JAVA中创建线程的三种方法及比较

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

    一、继承Thread类来创建线程

    1、创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run()方法,run()方法中的内容就是需要线程完成的任务。

    2、创建一个任务类的对象,即创建了线程对象。

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

    代码实例:

     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 }

    二、实现Runnable接口来创建线程

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

    2、创建一个任务类的对象。

    3、任务类必须在线程中执行,因此将任务类的对象作为参数,创建一个Thread类对象,该Thread类对象才是真正的线程对象。

    4、调用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 }

    三、通过Callable和Future来创建线程

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

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

    3、任务类必须在线程中执行,因此将FutureTask类的对象作为参数,创建一个Thread类对象,该Thread类对象才是真正的线程对象。

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

    5、调用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 }

    四、三种方式创建线程的比较

    1、继承Thread类方式:

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

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

    2、实现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()方法。

    3、通过Callable和Future的方式:

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

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

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

  • 相关阅读:
    typeof检测几种较为特殊的值与Boolean强制转换哪几种值为false Amy
    类型检测 Amy
    JS基本概念 Amy
    JS导入文件与CSS导入文件的不同 Amy
    JS运行环境 Amy
    主流浏览器及其渲染引擎 Amy
    JS引用类型 Amy
    同名函数的覆盖问题 Amy
    JS变量、作用域和内存问题 Amy
    HTTP协议学习(1)
  • 原文地址:https://www.cnblogs.com/pcheng/p/6905340.html
Copyright © 2011-2022 走看看