创建线程的4种方式以及实现的代码

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 https://blog.csdn.net/weixin_43863007/article/details/88840753

创建一个线程有四种方式:

  1. 继承Thread类创建线程
  2. 实现Runnable接口创建线程
  3. 使用Callable和Future创建线程
  4. 使用线程池例如用Executor框架

1.继承Thread类创建线程:

创建线程的步骤:

  1. 定义Thread类的子类,并重写该类的 run() 方法,该方法的方法体就是县城需要完成的任务,run() 方法也成为线程的执行体
  2. 创建Thread子类的实例,也就是创建了线程对象
  3. 启动线程,即调用线程的 Start() 方法

代码实例:

//继承Thread类
public class MyThread extends Thread{
  public void run(){
  	//重写run方法
  }
}

public class Main {
  public static void main(String[] args){
 		//创建并启动线程
    new MyThread().start();
  }
}

2.继承Thread类创建线程:

实现步骤:

  1. 定义Runnable接口的实现类,一样要重写 run() 方法和Thread中的 run() 方法一样是线程的执行体
  2. 创建Runnable 实现类的实例,并用这个实例作为Thread的 target 来创建 Thread 对象,这个Thread 对象才是真正的线程对象
  3. 第三步依然是通过调用线程对象的 start() 方法来启动线程

代码实例:

//实现Runnable接口
public class MyThread2 implements Runnable {
  public void run(){
  		//重写run方法
  }
}

public class Main {
  public static void main(String[] args){
    //创建并启动线程
    MyThread2 myThread=new MyThread2();
    Thread thread=new Thread(myThread);
    thread().start();
    //或者    new Thread(new MyThread2()).start();
  }
}

3.继承Thread类创建线程:

实现过程:

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

代码实例:

public class Main {
  public static void main(String[] args){
   MyThread3 th=new MyThread3();
   //使用Lambda表达式创建Callable对象
    //使用FutureTask类来包装Callable对象
   FutureTask<Integer> future=new FutureTask<Integer>(
    (Callable<Integer>)()->{
      return 5;
    }
    );
    //实质上还是以Callable对象来创建并启动线程
   new Thread(task,"有返回值的线程").start();
    try{
      //get()方法会阻塞,直到子线程执行结束才返回
    System.out.println("子线程的返回值:"+future.get());
    }catch(Exception e){
    ex.printStackTrace();
   }
  }
}

4.使用线程池例如用Executor框架:

Executor框架的最大优点是把任务的提交和执行解耦,要执行的任务的人只需要把Task描述清楚,然后提交即可,这个Task是怎么被执行的,被谁执行的,什么时候执行的提交的人就不用关心了,具体点将,提交一个Callable对象给ExecutorService(如最常用的线程池ThreadPoolExecutor)将得到一个Future对象,调用Future对象的get方法等待执行结果就好了,Executor框架的内部使用了线程池机制,它在Java.util.cocurrent包下,通过该框架控制线程的启动,执行和关闭,可以简化并法编程的操作,因此,在Java5之后,通过Executor来启动线程比使用Thread的Start方法更好,出了更易管理,效率更好外,还有关键的一点:有助于避免this逃逸问题–如果我们再构造器中启动一个线程,因为另一个任务可能会在构造器结束之前开始执行,此时肯呢个会访问到初始化了一半的对象用Executor在构造器中

猜你喜欢

转载自blog.csdn.net/weixin_43863007/article/details/88840753