• Java开启线程的四种方法


    1,继承Thread类

    继承Thread类,重写run方法(不推荐,因为java的单继承局限性)

     1 public class ExtendThread extends Thread {
     2 
     3     /*
     4     * 创建步骤如下:
     5     * 1,定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。因此把run方法称为线程执行体。
     6     * 2,创建Thread子类了的实例,即创建线程对象。本实例中是new一个ExtendThread,即可创建线程对象,也就是开启了一个线程
     7     * 3,调用线程对象的start()方法来启动该线程。
     8     *
     9     * 调用示例:
    10     * //循环10次即开启10个线程
    11     * for (int i = 0; i < 10; i++) {
    12     *     ExtendThread extendThread = new ExtendThread();
    13     *     extendThread.start();
    14     * }
    15     * */
    16 
    17     /**
    18      * 重写Thread类的run(),这个方法称为线程执行体
    19      * */
    20     @Override
    21     public void run() {
    22         doSomething();
    23     }
    24 
    25     /**
    26      * 需要处理的任务
    27      * */
    28     public void doSomething(){
    29         for (int i = 0; i < 10; i++) {
    30             System.out.println(Thread.currentThread().getName() + "执行" + i);
    31         }
    32     }
    33 }

    2,实现Runnable接口

    方式一:直接实现Runnable接口(避免单继承的局限性,方便共享资源,推荐使用)

     1 public class RunnableImpl implements Runnable {
     2 
     3     /*
     4     * 创建步骤如下:
     5     * 1,定义Runnable接口的实现类,并且实现run方法,这个方法同样是线程执行体
     6     * 2,创建Runnable实现类的实例,并以此实例对象作为Thread的target来创建Thread类,这个新创建的Thread对象才是真正的线程对象,即开启了新的线程
     7     * 3,调用线程对象的start()方法来开启该线程
     8     *
     9     * 调用示例:
    10     * //开启10个线程
    11     * for (int i = 0; i < 10; i++) {
    12     *     Thread thread = new Thread(new RunnableImpl());
    13     *     thread.start();
    14     * }
    15     * */
    16 
    17     /**
    18      * 实现Runnable接口的run方法,这个方法称为线程执行体
    19      * */
    20     @Override
    21     public void run() {
    22         doSomething();
    23     }
    24 
    25     /**
    26      * 需要处理的任务
    27      * */
    28     private void doSomething(){
    29         for (int i = 0; i < 10; i++) {
    30             System.out.println(Thread.currentThread().getName() + "执行" + i);
    31         }
    32     }
    33 }

    方式二:匿名内部类

     1 public class Anonymous {
     2 
     3     /*
     4     * 创建步骤如下:
     5     * 匿名内部类本质上也是一个类实现了Runnable接口,重写了run方法,只不过这个类没有名字,直接作为参数传入Thread类
     6     *
     7     * 调用示例:
     8     * //开启10个线程
     9     * for (int i = 0; i < 10; i++) {
    10     *     Anonymous anonymous =new Anonymous();
    11     *     anonymous.myRun();
    12     * }
    13     *
    14     * */
    15 
    16     public void myRun(){
    17         new Thread(new Runnable() {
    18             @Override
    19             public void run() {
    20                 doSomething();
    21             }
    22         }).start();
    23     }
    24 
    25     /**
    26      * 需要处理的任务
    27      * */
    28     private void doSomething(){
    29         for (int i = 0; i < 10; i++) {
    30             System.out.println(Thread.currentThread().getName() + "执行" + i);
    31         }
    32     }
    33 }

    3,实现Callable接口

     1 public class CallableImpl implements Callable<String> {
     2 
     3     /*
     4      * 创建步骤如下:
     5      * 1,定义实现Callable<V>接口的实现类,实现call方法,这个方法是线程执行体
     6      * 2,创建Callable<V>实现类的实例,借助FutureTask得到线程执行的返回值
     7      * 3,将FutureTask的实例,作为Thread的target来创建Thread类
     8      * 4,调用start方法,开启线程
     9      *
    10      * 调用示例:
    11      * Callable<String> tc = new CallableImpl();
    12      * FutureTask<String> task = new FutureTask<>(tc);
    13      * new Thread(task).start();
    14      * try {
    15      *     System.out.println(task.get());
    16      * } catch (InterruptedException | ExecutionException e) {
    17      *     e.printStackTrace();
    18      * }
    19      *
    20      * 说明:
    21      * 1.与使用Runnable相比, Callable功能更强大些
    22      * 2.实现的call()方法相比run()方法,可以返回值
    23      * 3.方法可以抛出异常
    24      * 4.支持泛型的返回值
    25      * 5.需要借助FutureTask类,比如获取返回结果
    26      * Future接口可以对具体Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等。
    27      * FutureTask是Futrue接口的唯一的实现类
    28      * FutureTask 同时实现了Runnable, Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
    29      *
    30      * */
    31 
    32     private int ticket = 5;
    33 
    34     @Override
    35     public String call() throws Exception {
    36         for (int i = 0; i < 10; i++) {
    37             System.out.println(doSomething());
    38         }
    39 
    40         return "出票任务完成";
    41     }
    42 
    43     public String doSomething() {
    44         String result = "";
    45         if (this.ticket > 0) {
    46             result = "出票成功,ticket=" + this.ticket--;
    47         } else {
    48             result = "出票失败,ticket=" + this.ticket;
    49         }
    50         return result;
    51     }
    52 }

    4,创建线程池

     1 public class ThreadPool implements Runnable {
     2 
     3     /*
     4      * 创建步骤如下:
     5      * 1,定义Runnable接口的实现类,或者定义(继承Runnable接口的类)的实现类,并且实现run方法,这个方法是线程执行体
     6      * 2,创建一个自定义线程个数的线程池
     7      * 3,实例化Runnable接口的实现类
     8      * 4,将3步的实例,作为线程池实例的execute方法的command参数,开启线程
     9      * 5,关闭线程池
    10      *
    11      * 调用示例:
    12      * ExecutorService pool = Executors.newFixedThreadPool(2);
    13      * ThreadPool threadPool = new ThreadPool("AA");
    14      * ThreadPool threadPoo2 = new ThreadPool("BB");
    15      * pool.execute(threadPool);
    16      * pool.execute(threadPoo2);
    17      * pool.shutdown();
    18      *
    19      * 说明:
    20      * 示例中创建的是2个线程的线程池
    21      * execute方法是开启线程方法,实参要求是实现Runnable的类。所以,继承Thread类的子类也可以以线程池的方式开启线程
    22      *
    23      * */
    24 
    25     String name;
    26     public ThreadPool(String name) {
    27         this.name = name;
    28     }
    29 
    30     @Override
    31     public void run() {
    32         doSomething();
    33     }
    34 
    35     /**
    36      * 需要处理的任务
    37      * */
    38     private void doSomething() {
    39         for (int i = 0; i < 10; i++) {
    40             System.out.println(Thread.currentThread().getName() + "执行" + i + ",name=" + this.name);
    41         }
    42     }
    43 }
  • 相关阅读:
    【博客申明】
    OAF客制化代码导出页面数据到Excel文件
    OAF调用JS代码
    Java冒泡排序
    Java二分查找代码
    Java 在某一个时间点定时执行任务(转载)
    Oracle 常用SQL
    Oracle数据字典
    spring3.0事务管理配置
    由override 和 overload 引发的学习感悟
  • 原文地址:https://www.cnblogs.com/huyueping/p/13858229.html
Copyright © 2020-2023  润新知