首页 > 编程语言 > 详细

线程的创建

时间:2020-07-20 14:29:46      阅读:61      评论:0      收藏:0      [点我收藏+]

线程的创建

方法一:继承于Thread类

步骤

  1. 创建一个继承于Thread类的子类
  2. 重写Thread类中的run( )方法
  3. 将此线程执行的操作声明在run方法中
  4. 创建Thread类的子类对象
  5. 通过此对象调用start( )方法
    • start方法作用
      • 启动当前线程
      • 调用当前线程的run( )方法

代码实现

public class Test1 {
    public static void main(String[] args) {
        //3. 创建Thread类的子类对象
        MyThread myThread = new MyThread();
        //4. 通过此对象调用start()方法
        myThread.start();
    }
}

//1. 创建一个继承于Thread类的子类
class MyThread extends Thread{
    //2. 重写Thread类中的run()方法
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
    }
}

注意事项

  1. 不能通过直接调用run()的方式去启动线程,启动线程只能使用start()方法
  2. 每个线程只能启动一次,如果多次启动,会报IllegalThreadStateException异常
  3. 要想创建多个线程,就造多个对象

方法二:实现Runnable接口

步骤

  1. 创建一个实现Runnable接口的类
  2. 实现类去实现Runnable类中抽象方法:run()
  3. 创建实现类的对象
  4. 将此对象作为参数传入到Thread类中的构造器中,创建Thread类的对象
  5. 通过Thread类的对象,调用start()
    • start()作用
      • 启动线程
      • 调用当前线程的run()
        • 调用了Runnable类型的target的run()

代码实现

public class Test2 {
    public static void main(String[] args) {
        //3. 创建实现类的对象
        MyselfThread myselfThread = new MyselfThread();
        //4. 将此对象作为参数传入到Thread类中的构造器中,创建Thread类的对象
        Thread thread = new Thread(myselfThread);
        //5. 通过Thread类的对象,调用start()
        thread.start();
    }
}

//1. 创建一个实现Runnable接口的类
class MyselfThread implements Runnable{
    //2. 实现类去实现Runnable类中的run()方法
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
    }
}

方法一和方法二对比

两者联系

  • Thread类本身也是实现了Runnable接口
  • 都需要重写run(),将线程要实现的逻辑声明在run()方法中

优先选择实现Runnable接口的方式

原因:

  1. 实现的方式没有类的单继承性的局限性
  2. 实现的方式更适合来处理多个线程有共享数据的情况

方法三:实现Callable接口

比Runnable相比的好处

  1. 可以有返回值
    • 需要借助Future接口
      • 可以对具体的Runnable、Callable任务的执行结果进行取消、查询是否完成获取结果等
      • 唯一的实现类是FutureTask
        • 同时实现了Runnable、Future接口
        • 既可以作为Runnable被线程执行,又可以作为Future得到
  2. 方法可以抛出异常,被外面的操作捕获,获取异常的信息
  3. 支持泛型的返回值

步骤

  1. 创建一个实现Callable接口的实现类
  2. 实现call方法,将此线程需要执行的操作声明在call方法中
    • call方法可以有返回值
  3. 创建Callable接口实现类的对象
  4. 将此Callable接口的实现类对象作为参数传递到FutureTask构造器中,创建FutureTask的对象
  5. 将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并start()方法调用
  6. 获取Callable中的call方法的返回值
    • 使用futureTask.get()
      • get()方法返回值即为FutureTask参数callable实现类重写call的返回值

代码实现

public class Test3 {
    public static void main(String[] args) {
        //3. 创建Callable接口实现类的对象
        NumThread numThread = new NumThread();
        //4. 将此Callable接口的实现类对象作为参数传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask futureTask = new FutureTask(numThread);
        //5. 将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并start()方法调用
        Thread thread = new Thread(futureTask);
        thread.start();
        //6. 获取Callable中的call方法的返回值
        try{
            Object sum = futureTask.get();
            System.out.println(sum);
        }catch (InterruptedException e){
            e.printStackTrace();
        }catch (ExecutionException e){
            e.printStackTrace();
        }
    }
}

//1. 创建一个实现Callable接口的实现类
class NumThread implements Callable{

    //2. 实现call方法,将此线程需要执行的操作声明在call方法中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 100; i++) {
            if(i % 2 == 0){
                sum = sum + i;
            }
        }
        return sum;
    }
}

方法四:使用线程池

好处

  1. 提高响应速度
  2. 降低资源消耗
  3. 便于线程管理

步骤

  1. 提供指定线程数量的线程池
  2. 执行指定的线程操作,需要提供一个实现Runnable接口或Callable接口实现类的对象
  3. 关闭连接池

线程的创建

原文:https://www.cnblogs.com/CrabDumplings/p/13344487.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!