Java创建多线程的三种常用方式

  1. 创建Thread子类
  1. 创建子类
  2. 在子类中重新run方法,设置线程任务
  3. 创建子类对象
  4. 调用start方法
    示例代码:
//1.创建Thread子类
public class MyThread1 extends Thread {
    //2.重写run方法,设置线程任务
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("MyThread1--->"+i);
        }
    }
}
public class demo1 {
    public static void main(String[] args) {
        //3.创建子类对象
        MyThread1 thread1 = new MyThread1();
        //4.调用对象start方法
        thread1.start();
        
        for (int i = 0; i < 10; i++) {
            System.out.println("main--->"+i);
        }
    }
}
  1. 实现Runnable接口
  1. 创建Runnable接口实现类
  2. 重写run方法,设置线程任务
  3. 创建实现类对象
  4. 创建Thread对象,构造方法中传递实现类对象
  5. 调用Thread对象的start方法开启线程
    示例代码:
//1.创建Runnable实现类
public class MyThread2 implements Runnable {
    //2.重新run方法,设置线程任务
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("MyThread2--->"+i);
        }
    }
}
public class demo2 {
    public static void main(String[] args) {
        //3.创建实现类对象
        MyThread2 thread2 = new MyThread2();
        //4.创建Thread类对象,构造方法传递实现类对象
        Thread thread = new Thread(thread2);
        //5.调用start方法
        thread.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("main--->"+i);
        }
    }
}
  1. 通过Callable和FutureTask接口创建线程
  1. 创建Callable实现类
  2. 重写call方法,设置方法体,可以有返回值
  3. 创建Callable实现类对象
  4. 创建FutureTask对象,将实现类对象传递给构造方法
  5. 调用FutureTask对象的run方法,执行线程
    示例代码:
//1.创建Callable实现类
public class MyThread3 implements Callable<Integer> {
    //2.重写call方法,设置方法体,可以有返回值
    @Override
    public Integer call() throws Exception {
        int num = 0;
        for (int i = 0; i < 10; i++) {
            System.out.println("MyThread3--->"+i);
            num+=i;
        }
        return num;
    }
}
public class demo3 {
    public static void main(String[] args) {
        //3.创建Callable实现类对象
        MyThread3 thread3 = new MyThread3();
        //4.创建FutureTask对象,将实现类对象传递给构造方法
        FutureTask<Integer> futureTask = new FutureTask<>(thread3);
        //5.调用FutureTask对象的run方法,执行线程
        futureTask.run();
        Integer num = 0;
        try {
            //使用FutureTask的get方法获取返回值
            num = futureTask.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("线程执行完后:"+num);
    }
}

三种方法比较

  • 通过继承Thread类实现多线程:
  • 优点
  • 实现起来简单;
  • 缺点
  • 线程类已经继承Thread类了,就不能再继承其他类;
  • 多个线程不能共享同一份资源;
  • 通过实现Runnable接口或者Callable接口实现多线程:
  • 优点:
  • 线程类只是实现了接口,还可以继承其他类;
  • 多个线程可以使用同一个Runnable实现类对象,适合多个线程处理同一份资源的情况。
  • 缺点:
  • 通过这种方式实现多线程较复杂;
  • 通过Callable和FutureTask接口创建线程
  • 返回结果的线程是在JDK1.5中引入的新特征,确实很实用,有了这种特征我就不需要再为了得到返回值而大费周折了

注意:不能对同一线程对象两次调用start()方法。


Thread类常用方法

  1. static Thread currentThread() :返回对当前正在执行的线程对象的引用。
  2. String getName() :返回此线程的名称。
  3. void setName(String name) :将此线程的名称更改为等于参数 name 。
  4. static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。
  5. boolean isAlive() :测试这个线程是否活着。
  6. void setPriority(int newPriority) :更改此线程的优先级。 Java使用的是抢占式线调度,优先级越高越容易抢到CPU。