3中常见的多线程创建方式

创建线程的3种方式

第一种方式是将类声明为 Thread 的子类。

  1. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。

  2. 创建Thread子类的实例,即创建了线程对象。

  3. 调用线程对象的start()方法来启动该线程。

      第一种方式:继承Thread类
    
/*
 * 1.定义一个子线程的类,继承Thread类;
 */
public class SubThread extends Thread {
 /*
  *2.在子线程类中重写run方法,在run方法中打印子线程的名称;
  */
 public void run() {
  // 打印子线程的名称
  System.out.println("subThread:" + Thread.currentThread().getName());
 }
}


/*
 * 3.定义一个测试类
 */
public class ThreadDemo {
  public static void main(String[] args) {
    // 4.在main方法中打印主线程的名称;
  System.out.println("main:" + Thread.currentThread().getName());
  // 5.在main方法中创建子线程对象;
  SubThread st = new SubThread();
  // 6.调用子线程对象的start方法,开启子线程。
  st.start();
 }
}

第二种方式是声明一个类实现Runnable 接口。

  1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

  2. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,Thread对象才是真正的线程对象。

  3. 调用线程对象的start()方法来启动线程。

     第二种方式:实现Runnable接口
    
/*
 * 1.定义一个子任务类,实现Runnable接口。
 */
public class SubRunnable implements Runnable {
    
    
 @Override
 public void run() {
    
    
  // 2.在子任务类中重写run方法,在run方法中打印子线程的名称。
  System.out.println("SubRunnable:"+ Thread.currentThread().getName());
 }
}


/*
 * 3.定义一个测试类。
 */
public class RunnableDemo {
    
    
 public static void main(String[] args) {
    
    
  // 4.在main方法中打印主线程的名称。
  System.out.println("RunnableDemo:"+ Thread.currentThread().getName());
  // 5.在main方法中创建一个子任务对象。
  SubRunnable r = new SubRunnable();
  // 6.在main方法中创建一个Thread类的对象,并把子任务对象传递给Thread类的                         构造方法。
  Thread t = new Thread(r);
  // 7.调用Thread类对象的start方法开启子线程。
  t.start();
 }
}

第三种方式:通过 Callable 和 Future 创建线程

1.创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
2.创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
3.使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
4.调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。

/**
 * 例子:遍历100以内的偶数,并计算100以内所有偶数的总和
 * 
 * 创建线程的方式:实现Callable接口
 */
//1.创建一个实现Callable的实现类
class NumThread implements Callable<Integer>{
    
    

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

public class ThreadNew {
    
    
    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方法
        new Thread(futureTask).start();

        try {
    
    
            //6.获取Callable中的call方法的返回值
            //get方法的返回值为FutureTask构造器参数Callable实现类重写的call方法的返回值。
            Object sum = futureTask.get();
            System.out.println("总和为:"+sum);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } catch (ExecutionException e) {
    
    
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_54455095/article/details/113741378