精华内容
下载资源
问答
  • 创建多线程的几种方式
    千次阅读
    2022-04-28 18:28:22

    序言

    1. 多线程

    • c++11中引入了线程类thread,头文件

      #include <thread>
      
    • 创建多线程的方法

      std::thread threadName(函数名, 参数1, 参数2, ...)
      
      std::thread threadName(functionName, leftValueArg, rightValueArg, std::ref(refArg), std::cref(constRefArg));
      

      传参可以传左值、右值、引用使用std::ref、const引用使用std::cref;
      参数先copy或move到std::thread对象,再move给函数

    • 程序至少有一个线程(主线程),一旦创建了std::thread对象也就是在主线程外创建了一个子线程,其立刻开始运行

    2. 多线程的创建

    常见的线程创建方式如下:

    1. 普通函数
    2. 成员函数
    3. 仿函数
    4. lambda函数
    
    • 线程创建方式1:普通函数
    #include <iostream>
    #include <thread>
    
    void Function(int a, int& b)
    {
        a = 2;
        b = 2;
    }
     
    int main()
    {
        int a = 1;
        int b = 1;
        // create sub-thread
        std::thread newThread(Function, a, std::ref(b));
    
        std::cout << a << " " << b << std::endl;
     
        // main thread waiting for sub-thread to finish
        newThread.join();
     
        return 0;
    }
    
    // 编译运行
    g++ --o main main.cpp -pthread
    
    • 线程创建方式2:成员函数
    #include <iostream>
    #include <thread>
    
    class MyClass {
    public:
    	void Function(const int& num)
    	{
    		std::cout << "I am " << num << " yeas old" << std::endl;
    	}
    };
    
    int main()
    {
        MyClass object;
        int num = 29;
    
        // create sub-thread
        std::thread newThread(&MyClass::Function, &object, std::cref(num));
    
        // main thread waiting for sub-thread to finish
        newThread.join();
     
        return 0;
    }
    
    • 线程创建方式3:仿函数
    #include <iostream>
    #include <thread>
    
    class MyClass {
    public:
    	void operator() (int& num)
    	{
    		std::cout << "sub-thread start" << std::endl; 
    		num = 30;
    		std::cout << "sub-thread end" << std::endl; 
    	}
    };
    
    int main()
    {
        std::cout << "main thread start" << std::endl;
        
        MyClass object;
        int num = 29;
    
        std::cout << "num = " << num << std::endl;
        
        // create sub-thread
        std::thread newThread(object, std::ref(num));
        // std::thread newThread(MyClass(), std::ref(num)); 也可
    
        // main thread waiting for sub-thread to finish
        newThread.join();
     
        std::cout << "num = " << num << std::endl;
        std::cout << "main thread end" << std::endl;
        
        return 0;
    }
    
    // 上面的例子,也可如下实现
    ...
    int main()
    {
    	// MyClass object;	// no need to create object
    	std::thread newThread(MyClass(), std::ref(num));
    	...
    }
    
    • 线程创建方式4:匿名函数lambda
    #include <iostream>
    #include <thread>
    
    int main()
    {
        auto function = [](int a) { std::cout << a << '\n'; };
    
        // create sub-thread
        std::thread newThread(function, 10);
    
        newThread.join();
    
        return 0;
    }
    
    // 或以如下方式调用lambda函数
    #include <iostream>
    #include <thread>
    
    int main()
    {
        // create sub-thread
        std::thread newThread([](int a) {std::cout << a << std::endl;}, 10);
    
        newThread.join();
    
        return 0;
    }
    

     


    参考文章:

    多线程与单线程的对比
    线程创建的几种方式
    cpp官网线程创建的几种方式
    ros多线程创建

    created by shuaixio, 2022.04.30

    更多相关内容
  • 创建多线程(8种方式

    千次阅读 2022-03-29 20:21:43
    无论有多少种形式,创建多线程的真正的方法, 其实只有两种: > 继承 Thread 类 > 实现 Runnable 接口 其它形式都是这两种方式的变体。 1、继承 Thread 类 ①实现方式 第一步:继承 Thread 类 第二步...

    无论有多少种形式,创建多线程的真正的方法,

    其实只有两种:

             > 继承 Thread 类

            > 实现 Runnable 接口

    其它形式都是这两种方式的变体。

    1、继承 Thread 类

    ①实现方式

    • 第一步:继承 Thread 类
    • 第二步:重写 run() 方法
    • 第三步:创建 Thread 子类对象
    • 第四步:调用 start() 方法启动线程

    ②start() 方法和 run() 方法区别

    调用 run() 方法仅仅只是调用了一个子类中重写的父类方法,并没有真正开启一个新的线程,还是在当前线程运行,也就是 main 线程。

    ③评价

    因为 Java 是单继承的,一个类继承了 Thread 类就不能继承其它类,所以通常不采用这个办法创建多线程。

    2、实现 Runnable 接口

    ①实现 Runnable 接口形式

    public class CreateThread02Impl {
    
        public static void main(String[] args) {
    
            // 第四步:创建实现了 Runnable 接口的类的对象
            MyRunnableThread runnable = new MyRunnableThread();
    
            // 第五步:创建 Thread 类对象
            // 参数1:runnable 对象
            // 参数2:线程名称
            Thread thread = new Thread(runnable, "thread 002");
    
            // 第六步:调用 Thread 对象的 start() 方法启动线程
            thread.start();
        }
    
    }
    
    // 第一步:实现 Runnable 接口
    class MyRunnableThread implements Runnable {
    
        // 第二步:实现 run() 方法
        @Override
        public void run() {
    
            // 第三步:编写线程中的逻辑代码
            System.out.println(Thread.currentThread().getName() + " is working");
        }
    }

    ②匿名内部类形式

    // 第一步:以匿名内部类的方式创建 Runnable 接口类型的对象
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // 第二步:编写线程中的逻辑代码
            System.out.println(Thread.currentThread().getName() + " is working");
        }
    };
    
    // 第三步:创建 Thread 类对象
    // 参数1:runnable 对象
    // 参数2:线程名称
    Thread thread = new Thread(runnable, "thread 003");
    
    // 第四步:调用 Thread 对象的 start() 方法启动线程
    thread.start();

    ③Lambda 表达式形式

    // 编写 Lambda 表达式的口诀:
    // 复制小括号
    // 写死右箭头
    // 落地大括号
    
    // 第一步:以匿名内部类的方式创建 Runnable 接口类型的对象
    Runnable runnable = () -> {
        // 第二步:编写线程中的逻辑代码
        System.out.println(Thread.currentThread().getName() + " is working");
    };
    
    // 第三步:创建 Thread 类对象
    // 参数1:runnable 对象
    // 参数2:线程名称
    Thread thread = new Thread(runnable, "thread 004");
    
    // 第四步:调用 Thread 对象的 start() 方法启动线程
    thread.start();

    3、使用 Callable 接口配合 FutureTask

     在JDK1.5提供了Future和Callable的实现,可以用于阻塞式获取结果

    该方案最核心的价值是:使用 Callable 接口限定的功能 + Future 接口限定的功能 = 汇总各个线程执行结果

    最终执行汇总操作的这一步会被阻塞,直到前面各个线程完成了计算。

    ①FutureTask类和Runnable接口的关系

    从继承关系能够看到,FutureTask本身也间接实现了Runnable接口。FutureTask类的对象也是Runnable接口的实例,可以用于在创建Thread对象时,传入Thread构造器。

    ②Future 接口

    boolean cancel(boolean mayInterruptIfRunning);
    如果尚未启动,它将停止任务。如果已启动,则仅在 mayInterrupt 为 true 时才会中断任务。
    
    V get() throws InterruptedException, ExecutionException;
    如果任务完成,它将立即返回结果,否则将等待任务完成,然后返回结果。
    
    boolean isDone();
    如果任务完成,则返回true,否则返回false。
    

     ③FutureTask 类的构造器

    【1】.介绍:

    FutureTask 类兼具 Runnable 和 Future 接口的功能,并方便地将两种功能组合在一起。关于 FutureTask 类的使用有如下建议:

    • 在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给 Future 对象在后台完成
    • 当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执行状态
    • 一般 FutureTask 多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。
    • 仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get() 方法
    • 一旦计算完成,就不能再重新开始或取消计算
    • get() 方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常
    • get() 只执行一次,因此get() 方法放到最后

    【2】可以使用的构造器

        public FutureTask(Callable<V> callable) {
            if (callable == null)
                throw new NullPointerException();
            this.callable = callable;
            this.state = NEW;       // ensure visibility of callable
        }

    根据这个构造器,我们知道,创建 FutureTask 对象时,传入一个 Callable 类型的对象即可。

    ④Callable 接口

    @FunctionalInterface
    public interface Callable<V> {
        /**
         * Computes a result, or throws an exception if unable to do so.
         *
         * @return computed result
         * @throws Exception if unable to compute a result
         */
        V call() throws Exception;
    }

    从 call() 方法的声明我们可以看出,它有一个返回值。这个返回值可以将当前线程内计算结果返回。

    ⑤测试代码

    // 1.创建三个FutureTask对象,封装三个线程的执行逻辑
    FutureTask<Integer> task01 = new FutureTask<>(() -> {
    
        int result = (int) (Math.random() * Math.random() * 100);
    
        System.out.println(Thread.currentThread().getName());
    
        return result;
    });
    FutureTask<Integer> task02 = new FutureTask<>(() -> {
    
        int result = (int) (Math.random() * Math.random() * 1000);
    
        System.out.println(Thread.currentThread().getName());
    
        return result;
    });
    FutureTask<Integer> task03 = new FutureTask<>(() -> {
    
        int result = (int) (Math.random() * Math.random() * 10000);
    
        System.out.println(Thread.currentThread().getName());
    
        return result;
    });
    
    // 2.创建三个线程对象,然后启动线程
    new Thread(task01, "thread01").start();
    new Thread(task02, "thread02").start();
    new Thread(task03, "thread03").start();
    
    // 3.上面三个线程执行完成后,可以收集它们各自运算的结果
    Integer task01Result = task01.get();
    Integer task02Result = task02.get();
    Integer task03Result = task03.get();
    
    System.out.println("task01Result = " + task01Result);
    System.out.println("task02Result = " + task02Result);
    System.out.println("task03Result = " + task03Result);

    ⑥Callable和Runnable对比

    Runnable接口

    Callable接口

    重写run()方法

    重写call()方法

    run()没有返回值

    call()有返回值

    run()没有声明抛出异常

    call()声明抛出Exception

    没有汇总各个线程结果的机制

    有汇总各个线程结果的机制

    ⑦Callable接口方案的特点

    该方案仅在具体任务计算完成时才能检索结果;如果计算尚未完成,则阻塞 get() 方法。一旦计算完成,就不能再重新开始或取消计算。get() 方法获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常, 且只计算一次。

    4、线程池

    1.参考代码

    // 1.创建线程池对象
    ExecutorService pool = Executors.newFixedThreadPool(5);
    
    // 2.给线程池对象分配任务,每一个任务是一个线程
    pool.execute(() -> {
        System.out.println(Thread.currentThread().getName() + " " + new Date());
    });
    
    pool.execute(() -> {
        System.out.println(Thread.currentThread().getName() + " " + new Date());
    });
    
    pool.execute(() -> {
        System.out.println(Thread.currentThread().getName() + " " + new Date());
    });

    2.开发建议:

    阿里开发手册中对线程创建的规定:

    结论:实际开发中,建议使用『自定义线程池』的方式创建多线程。在创建自定义线程池时,使用合理的参数。

    5.CompletableFuture

    这个completableFuture是JDK1.8版本新引入的类。下面是这个类。实现了俩接口。本身是个class。这个是Future的实现类。

     

    CompletableFuture提供了四个静态方法用来创建CompletableFuture对象:

    public static CompletableFuture<Void>   runAsync(Runnable runnable)
    public static CompletableFuture<Void>   runAsync(Runnable runnable, Executor executor)
    public static <U> CompletableFuture<U>  supplyAsync(Supplier<U> supplier)
    public static <U> CompletableFuture<U>  supplyAsync(Supplier<U> supplier, Executor executor)

    Asynsc表示异步,而supplyAsyncrunAsync不同在与前者异步返回一个结果,后者是void.第二个函数第二个参数表示是用我们自己创建的线程池,否则采用默认的ForkJoinPool.commonPool()作为它的线程池.其中Supplier是一个函数式接口,代表是一个生成者的意思,传入0个参数,返回一个结果.

    - runAsync方法不支持返回值。

    - supplyAsync可以支持返回值。

     计算完成时回调方法

    public CompletableFuture<T>     whenComplete(BiConsumer<? super T,? super Throwable> action)
    public CompletableFuture<T>     whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
    public CompletableFuture<T>     whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
    public CompletableFuture<T>     exceptionally(Function<Throwable,? extends T> fn)

    whenComplete可以处理正常或异常的计算结果

    exceptionally处理异常情况

    BiConsumer<? super T,? super Throwable>可以定义处理业务

    whenComplete 和 whenCompleteAsync 的区别:

    • whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。

    • whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。

    ==注意:方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)==

    线程串行化与并行化方法

    thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值

    public <U> CompletableFuture<U>     thenApply(Function<? super T,? extends U> fn)
    public <U> CompletableFuture<U>     thenApplyAsync(Function<? super T,? extends U> fn)
    public <U> CompletableFuture<U>     thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)

    thenAccept方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。

    public CompletableFuture<Void>  thenAccept(Consumer<? super T> action)
    public CompletableFuture<Void>  thenAcceptAsync(Consumer<? super T> action)
    public CompletableFuture<Void>  thenAcceptAsync(Consumer<? super T> action,
                                                         Executor executor)

    thenRun方法:只要上面的任务执行完成,就开始执行thenRun,只是处理完任务后,执行 thenRun的后续操作

    public CompletableFuture<Void> thenRun(Runnable action)
    public CompletableFuture<Void> thenRunAsync(Runnable action)
    public CompletableFuture<Void> thenRunAsync(Runnable action,
                                                    Executor executor)

    带有Async默认是异步执行的。这里所谓的异步指的是不在当前线程内执行。

    6、并行计算[了解]

    List<String> list = Arrays.asList("a", "b", "c", "d", "e");
    
    // 串行计算
    list.stream().forEach(System.out::print);
    
    System.out.println();
    
    // 并行计算
    list.parallelStream().forEach(System.out::print);

     7、Timer 定时任务[了解]

    // 1、创建 Timer 对象封装定时任务中要执行的操作
    // 每一个 Timer 对象会使用一个线程来执行定时任务
    Timer timer01 = new Timer();
    
    // 2、调用 schedule() 指定任务和执行周期
    // 参数1:timerTask 封装具体任务操作
    // 参数2:delay 指定定时任务延迟多久后开始执行
    // 参数3:period 指定定时任务执行的时间间隔
    timer01.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() +" is working");
        }
    }, 0, 1000);
    
    Timer timer02 = new Timer();
    
    timer02.schedule(new TimerTask() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() +" is working");
        }
    }, 0, 1000);

    8、Spring 异步方法[了解]

    在 Spring 环境下,如果组件 A(假设是 ControllerA)要调用组件 B(假设是 ServiceB)的多个方法,而且希望这些方法能够异步执行。

    [1]开启异步功能

    在主启动类使用 @EnableAsync 注解:

    // 开启支持异步方法调用功能
    @EnableAsync
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }

    [2]标记异步方法

    在想要异步调用的方法上使用 @Async 注解:

    @Service
    public class DemoService {
    
        // 在想要实现异步调用的方法上加 @Async注解
        @Async
        public void doSth() {
            System.out.println("Demo Service " + Thread.currentThread().getName());
        }
    
    }

    展开全文
  • 创建线程几种方式

    千次阅读 2019-04-12 12:07:59
    创建线程几种方式: 方式1:通过继承Thread类创建线程 步骤:1.定义Thread类的子类,并重写该类的run方法,该方法的方法体就是线程需要执行的任务,因此run()方法也被称为线程执行体 2.创建Thread子类的实例,...

    创建线程的几种方式:
    方式1:通过继承Thread类创建线程
    步骤:1.定义Thread类的子类,并重写该类的run方法,该方法的方法体就是线程需要执行的任务,因此run()方法也被称为线程执行体
    2.创建Thread子类的实例,也就是创建了线程对象
    3.启动线程,即调用线程的start()方法

    在这里插入图片描述
    方式2:通过实现Runnable接口创建线程
    步骤:1.定义Runnable接口的实现类,一样要重写run()方法,和第一种方式一样,这里的run()方法也是线程的执行体
    2.创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread类才是真正的线程对象
    3.依然是通过调用线程对象的start方法来启动线程
    在这里插入图片描述
    方式3:使用Callable和Future来创建线程
    注意:和Runnable接口不一样,Callable接口提供了一个call()方法来作为线程的执行体,call()方法比run()方法功能要更加强大,call()方法可以有返回值,call()方法可以声明抛出异常(前两种如果要抛异常只能通过try,catch来实现)。
    步骤:1.创建Callable接口的实现类,并实现call()方法,然后创建该类的实例
    2.使用Future Task类来包装Callable对象。该FutureTask对象封装了Callable对象的call()方法的返回值
    3.使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口并在重写的run方法中执行call方法)
    4.调用FutureTask对象的get方法来获取线程执行结束后的返回值
    在这里插入图片描述

    方法4:通过线程池来创建线程
    注意:ExecutorService es = Executors.newFixedThreadPool(30);
    ExecutorService es = Executors.newCachedThreadPool();
    FixedThreadPool创建的线程池-》用户可以指定线程池大小,但指定了就不可变
    CachedThreadPool创建的线程池-》线程池大小可变
    在这里插入图片描述
    几种创建线程方式的对比:
    实现Runnable和实现Callable接口方式基本相同,不过是后者执行call方法并且有返回值,而run方法无任何返回值,因此可以把这两种方式归为一种方式与继承Thread类的方式进行对比,差别如下(以实现接口方式为主):
    1.线程只是实现Runnable接口或Callable接口,还可以继承其他类(有点像接口和抽象类的区别,java是单继承的,但可以实现多个接口)
    2.实现接口的方式多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形
    3.如果需要访问当前线程,必须调用Thread.currentThread方法
    4.继承Thread类的线程类不能再继承其他父类(java单继承决定)
    因此,一般推荐采用实现接口的方式来创建线程。

    展开全文
  • 创建线程几种方式

    万次阅读 2021-08-23 09:39:14
    Java中创建线程主要有三种方式: 一、继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。 (2)创建Thread子类的实例...

    Java中创建线程主要有三种方式:

    一、继承Thread类创建线程类

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

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

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

    
    public class FirstThreadTest extends Thread {
    
        int i = 0;
    
        //重写run方法,run方法的方法体就是现场执行体
        public void run() {
            for (; i < 100; i++) {
                System.out.println(getName() + "  " + i);
            }
        }
    
        public static void main(String[] args) {
    
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + "  : " + i);
                if (i == 50) {
                    new FirstThreadTest().start();
                    new FirstThreadTest().start();
                }
            }
        }
    }
    

    上述代码中Thread.currentThread()方法返回当前正在执行的线程对象。GetName()方法返回调用该方法的线程的名字。

    二、通过Runnable接口创建线程类

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

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

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

    public class RunnableThreadTest implements Runnable{
            private int i;
            public void run()
            {
                for(i = 0;i <100;i++)
                {
                    System.out.println(Thread.currentThread().getName()+" "+i);
                }
            }
            public static void main(String[] args)
            {
                for(int i = 0;i < 100;i++)
                {
                    System.out.println(Thread.currentThread().getName()+" "+i);
                    if(i==20)
                    {
                        RunnableThreadTest rtt = new RunnableThreadTest();
                        new Thread(rtt,"新线程1").start();
                        new Thread(rtt,"新线程2").start();
                    }
                }
    
            }
    }
    

    三、通过Callable和Future创建线程

    (1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。

    (2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。注释:FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了Future和Runnable接口。

    (3)使用FutureTask对象作为Thread对象的target创建并启动新线程。

    (4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

    package com.nf147.Constroller;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class CallableThreadTest implements Callable<Integer> {
    
    
        public static void main(String[] args) {
            CallableThreadTest ctt = new CallableThreadTest();
            FutureTask<Integer> ft = new FutureTask<>(ctt);
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + " 的循环变量i的值" + i);
                if (i == 20) {
                    new Thread(ft, "有返回值的线程").start();
                }
            }
            try {
                System.out.println("子线程的返回值:" + ft.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public Integer call() throws Exception {
            int i = 0;
            for (; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
            return i;
        }
    }
    

    四、创建线程的三种方式的对比

    1.采用实现Runnable、Callable接口的方式创见多线程时,优势是:

    (1)线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。

    (2)在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

    劣势是:

    (1)编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

    2.使用继承Thread类的方式创建多线程时优势是:

    (1)编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

    劣势是:

    (1)线程类已经继承了Thread类,所以不能再继承其他父类。

    展开全文
  • 多线程创建几种方式

    千次阅读 2020-04-26 21:55:54
    并把需要多线程运行的程序放到 public void run() 方法里。 启动:在主函数中,new 出 MyThread1 类的实例。 运行:调用 MyThread1类的实例的 start() 方法即可。 第二种方式创建:编写一个类 MyThrea...
  • 作为java程序开发,离不开spring,那么在spring中怎么创建多线程并将注册到spring的类在多线程中使用呢?我自己总结了一下,可以有两种方式,使用线程池和spring自带多线程注解使用。 使用线程池 我一般使用固定...
  • 创建多线程的四种方式

    千次阅读 2020-06-27 22:45:51
    一、继承Thread类 步骤 定义一个类继承Thread类 重写run方法:里面写线程要运行的任务代码 创建Thread子类对象 ... // 创建Thread的子类对象,创建线程。 Demo d1 = new Demo("张三"); Demo d2 = new
  • 线程几种创建方式

    千次阅读 2022-03-01 15:03:28
    今天突然用到线程池,就复习下线程这块,记录下工作中常用的知识
  • 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、pandas是什么? 前言 ...示例:pandas 是基于NumPy 的一工具,该工具是为了解决数据分析任务而创建的。 ...
  • 若一个进程中同一时间并行执行多个线程,就是支持多线程的。线程作为调度和执行的单位,每个线程都拥有独立的运行栈和程序计数器,一个进程中的多个线程共享相同的内存单元/内存地址空间——>他们从
  • 如何创建线程创建线程几种方法?怎么实现的?
  • 多线程几种实现方式

    千次阅读 2020-08-02 18:08:57
    1.使用实现多线程有四种方式:①继承Thread类;②实现Runnable接口;③使用Callable和FutureTask实现有返回值的多线程;④使用ExecutorService和Executors工具类实现线程池(如果需要线程的返回值,需要在线程中实现...
  • 线程创建常用的四种方式

    千次阅读 2021-03-24 16:28:17
    Java可以用四种方式创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线程 3)使用Callable和Future创建线程 4)使用线程池例如用Executor框架 下面让我们分别来看看这四种创建线程的...
  • 创建线程的四种方式

    千次阅读 2019-11-21 00:29:29
    1. 线程创建有四种方式 2. 继承Thread类 3. 实现Runnable接口 4.实现Callable接口 5.线程池创建线程 1. 线程创建有四种方式,分别为: 继承Thread类 实现Runnable接口 实现Callable接口 使用Executor...
  • C++多线程的6种创建方法

    千次阅读 2021-12-12 17:32:33
    创建线程: 包含头文件,调用thread类创建一个线程对象; #include <thread> #include <iostream> using namespace std; void print(){ cout<<"子线程"<<endl; } int main(){ thread ...
  • 用Python创建多线程几种方法

    千次阅读 2019-06-01 16:40:48
    经过总结,Python创建多线程主要有如下两方法: 函数 类 接下来,我们就来揭开多线程的神秘面纱。 学会使用函数创建多线程 在Python3中,Python提供了一个内置模块threading.Thread,可以很方便地让我们创建...
  • java有以下四种创建多线程方式: 1:继承Thread类创建线程 2:实现Runnable接口创建线程 3:使用Callable和FutureTask创建线程 4:使用线程池,例如用Executor框架创建线程 DEMO代码: package thread; ...
  • Java创建多线程的五方法

    千次阅读 2021-12-31 15:01:09
    Java创建多线程的五方法总结
  • java创建多线程的四种方式及其区别

    千次阅读 2019-04-26 18:35:25
    java创建多线程有如下四种方式: 继承Thread类创建线程 实现Runnable接口创建线程 使用Callable和Future创建线程 使用线程池创建(使用java.util.concurrent.Executor接口) 下面分别介绍这四种创建多线程的方式...
  • JAVA多线程的三种创建方式

    万次阅读 多人点赞 2019-03-03 16:24:47
    一、概述 在JAVA中,用Thread类代表线程,所有线程对象,都必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行一段顺序执行的代码,JAVA使用线程执行体来...通过继承Thread类来创建并启动多线程的步骤...
  • 线程创建方式和区别 1.继承Thread类 (1)创建Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。 (2)创建了Thread子类的实例,即创建线程对象。...
  • java 创建线程的三种方式创建线程池的四种方式

    万次阅读 多人点赞 2019-02-23 21:01:44
    java创建线程的三种方式: 继承Thread类创建线程类 实现Runnable接口 通过Callable和Future创建线程 java创建线程池的四种方式: newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理...
  • Java创建多线程的8种方式

    万次阅读 多人点赞 2018-07-21 21:16:51
    目录 Java创建启动线程的多种方式 1、继承Thread类,重写run()方法 2、实现Runnable接口,重写run() 3、匿名内部类的方式 4、带返回值的线程(实现...)————以上3种方式,都没有返回值且都无法抛出异...
  • java创建线程的三种方式

    千次阅读 2022-06-05 22:10:43
    线程创建的三种方式及其对比
  • 创建多线程几种方法

    千次阅读 2017-11-29 22:23:00
    创建线程的几种方式多线程有三种实现方法: 1、继承Thread类,重写run()方法。然后直接new这个对象的实例,创建一个线程的实例,再调用start()方法启动线程。(其实本质上Thread是实现了...
  • 其中第一、二中最为简单,我已经在前面线程部分详细解释过,不懂得可以去看看:多线程。 今天我们聊聊其他两和他们的区别。 1、使用Callable接口和Future创建线程 和Runnable接口不一样,Callable接口提供了一个...
  • 创建线程几种方式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 612,386
精华内容 244,954
关键字:

创建多线程的几种方式