精华内容
下载资源
问答
  • 启动线程体的方法
    2019-03-28 15:23:46

    1、写一个类继承自Thread类,重写run方法。用start方法启动线程

    2、写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动

    多线程原理

    :相当于玩游戏机,只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。

    调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。

    1.start()

    方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要

    更多相关内容
  • 线程之间的执行是相互独立的,哪一个线程优先执行取决于OS的调度 线程的创建方式: 实现Runnable接口: ...调用thread实例的start,启动线程; 普通方式 package ThreadDemo; class Thread1 i...
    线程之间的执行是相互独立的,哪一个线程优先执行取决于OS的调度

    线程的创建方式:

    实现Runnable接口:

    • 创建自定义类并实现runnable接口,且实现接口中的run方法;
    • 实例化自定义的类;
    • 将自定义类的实例作为参数传给Thread类,创建thread实例;
    • 调用thread实例的start,启动子线程;
    普通方式
    package ThreadDemo;
    
    class Thread1 implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"子线程");
        }
    }
    public class RunnableDemo {
        public static void main(String[] args) {
              Thread1 thread1=new Thread1();
              Thread thread=new Thread(thread1);
              thread.start();
        }
    }
    
    
    lambda表达式呈现:
    public class RunnableDemo {
        public static void main(String[] args) {
              Thread thread=new Thread(()->{
                  System.out.println(Thread.currentThread().getName()+"子线程");
              });
              thread.start();
        }
    }
    

    继承Thread类创建线程

    • 创建自定义类并继承Thread类,并且重写run方法;
    • 实例化自定义类
    • 通过实例化对象调用start方法来创建线程;
    package ThreadDemo;
    
    class Thread1 extends Thread{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"子线程");
        }
    }
    public class RunnableDemo {
        public static void main(String[] args) {
              Thread1 thread1=new Thread1();
              thread1.start();
        }
    }
    
    

    实现Callable接口:线程池提供的一种创建线程的方式;

    • 实现Callable接口,并实现它的call方法;
    • 创建线程池(Executors工具类提供的方法创建线程池);
    • 创建Callable接口实现类的实例;
    • 将实例对象通过线程池的submit(提交)方法提交给线程池进而创建新的线程;
    package ThreadDemo;
    
    import java.util.concurrent.*;
    
    class Thread2<T> implements Callable<T> {
        @Override
        public T call() throws Exception {
            System.out.println(Thread.currentThread().getName());
            return null;
        }
    }
    public class RunnableDemo {
        public static void main(String[] args) {
            ExecutorService executor= Executors.newSingleThreadExecutor();
             Thread2<Integer> thread2=new Thread2();
             Future<Integer>future= executor.submit(thread2);
            try {
                Integer integer=future.get();
                future.cancel(true);
                //用于取消异步的任务,它传入一个boolean类型的参数,传入true会中断线程停止任务,
                // 而传入false则会让线程正常执行至完成,并返回false。 
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    线程操作的相关方法介绍:

    • void start(): 启动一个新的线程,start方法必须是子线程第一个调用的方法,start方法不能够重复调用(否则会抛异常),新线程会调用runnable接口提供的run方法;
    • void run(): run方法是子线程的执行体,子线程从进入run方法开始直至run方法结束,意味着子线程的任务执行结束;在主线程直接调用run方法是不能创建子线程的,只是普通方法调用;
    • yield(): 让步或者暂停,Thread类的静态方法。让正在执行的线程停止或者让步,让给优先级较高的线程获取CPU的执行权(不一定会让出CPU执行权,如等待的线程优先级较低或者当前线程只有一个线程在执行时,那么当前线程又会立即获取CPU的执行权)
      thread.yield() == 》 thread != 正在执行的线程 ==》 静态方法通过实例调用,但是跟实例没有任何关系;
    • static native void sleep(long millis) throws InterruptedException: sleep方法作用是让线程进行休眠,即让线程阻塞住,Thread类提供的静态方法,会抛出InterruptedException异常;
    • join(): 等待线程执行结束才继续执行,会抛出InterruptedException异常;
      假如在a线程中b线程进行 b.join() 调用,那么a线程执行结束才能继续执行,控制多线程按照次序执行;
    • interrupt(): 中断方法,底层调用native方法,native方法的作用是对特定标识位做出修改,主要作用于线程:运行中线程,阻塞线程(sleep/join)
      运行中线程: interrupt方法仅仅是对标志位做了修改,其它没有影响;
      阻塞线程: interrupt方法对标志位做了修改,另阻塞中的线程感知到标志位做了修改,就会中断当前的阻塞状态,抛出InterruptedException异常;
    • boolean isInterrupted(): 判断是否发生了中断操作,true表示发生了中断,false 表示未发生中断;
    • setPriority(int newPriority): 设置线程优先级,优先级分为10级,优先级数字越大,即优先级越高,优先级越高,被优先调用的概率会增大;但是不一定会被优先执行,还是要看本地操作系统的
      MIN_PRIORITY=1; 最小优先级;
      NORM_PRIORITY=5 ; 默认优先级;
      MAX_PRIORITY=10 ; 最大优先级;
    • int getPriority(): 返回当前程序的优先级;
    • setDaemon(boolean on): 设置守护线程,true:设置为守护线程,false:用户线程; 线程不进行设置,默认为用户线程;
    • boolean isDaemon(): 判断当前线程是否为守护线程;

    守护线程:

    脱离于控制终端,作为提供通用服务的线程存在。

    用户线程和守护线程的区别:

    • 生命周期:守护线程的生命周期是依赖于用户线程,当有用户线程存在,守护线程就会存活,当没有用户线程存在,那么守护线程也会随之消亡。垃圾回收是有单独线程来处理的,负责垃圾回收的线程就是守护线程;

    为什么sleep和yield方法是静态的:

    sleep分析:为什么不设计成非静态的,当实例调用时,该实例休眠 ?

    • 如果是实例方法,就可以实现在一个线程里随时让其它线程在执行中休眠,而且这种休眠是不放弃锁的。那么这种简单粗暴就很容易引起混乱,因此目前这种机制其实就是一种限制:你可以选择给自己吃安眠药,而不能随便给正在工作的别人吃安眠药;

    • 线程和实例并不是对等的,不是一个线程是一个实例,是你创建的实例继承了Thread或者Runable,实现了run(),并调用start()的时候能执行多个线程,实例还是一个,线程却是多个。所以实例休眠线程就休眠了这个假设不成立。

    yield分析:

    yield()是建议线程调度程序从当前线程中让出CPU时间给别的线程,这是一种总体调度,不是仅仅和某个线程相关的,而是和每个线程都有关。线程和人不一样,不是当前线程让了,别的线程就会来抢,是需要调度程序来调度的。

    关于sleep()方法和yield()方法的区别如下:

    • sleep()方法暂停当前线程后,会给其他线程执行机会,不会理会其他线程的优先级;但yield()方法只会给优先级相同,或优先级更高的线程执行机会。

    • sleep()方法会将线程转入阻塞状态,直到经过阻塞时间才会转入就绪状态;而yield()方法不会将线程转入阻塞状态,它只是强制当前线程进入就绪状态。因此完全有可能某个线程调用yield()方法暂停之后,立即再次获得处理器资源被执行。

    • sleep()方法声明抛出了InterruptedException异常,所以调用sleep()方法时要么捕捉该异常,要么显式声明抛出该异常;而yield()方法则没有声明抛出任何异常。

    • sleep()方法比yield()方法有更好的可移植性,通常不建议使用yield()方法来控制并发线程的执行。

    展开全文
  • JAVA开启线程的四种方法

    千次阅读 2021-12-21 16:48:00
    * 1,定义Thread类的子类,并重写该类的run()方法,该run()方法方法体就代表了线程需要完成的任务。因此把run方法称为线程执行。 * 2,创建Thread子类了的实例,即创建线程对象。本实例中是new一个...

    1,继承Thread类

    继承Thread类,重写run方法(不推荐,因为java的单继承局限性)

    public class ExtendThread extends Thread {
    
        /*
        * 创建步骤如下:
        * 1,定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。因此把run方法称为线程执行体。
        * 2,创建Thread子类了的实例,即创建线程对象。本实例中是new一个ExtendThread,即可创建线程对象,也就是开启了一个线程
        * 3,调用线程对象的start()方法来启动该线程。
        *
        * 调用示例:
        * //循环10次即开启10个线程
        * for (int i = 0; i < 10; i++) {
        *     ExtendThread extendThread = new ExtendThread();
        *     extendThread.start();
        * }
        * */
    
        /**
         * 重写Thread类的run(),这个方法称为线程执行体
         * */
        @Override
        public void run() {
            doSomething();
        }
    
        /**
         * 需要处理的任务
         * */
        public void doSomething(){
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "执行" + i);
            }
        }
    }

    2,实现Runnable接口

    方式一:直接实现Runnable接口(避免单继承的局限性,方便共享资源,推荐使用)

    public class RunnableImpl implements Runnable {
    
        /*
        * 创建步骤如下:
        * 1,定义Runnable接口的实现类,并且实现run方法,这个方法同样是线程执行体
        * 2,创建Runnable实现类的实例,并以此实例对象作为Thread的target来创建Thread类,这个新创建的Thread对象才是真正的线程对象,即开启了新的线程
        * 3,调用线程对象的start()方法来开启该线程
        *
        * 调用示例:
        * //开启10个线程
        * for (int i = 0; i < 10; i++) {
        *     Thread thread = new Thread(new RunnableImpl());
        *     thread.start();
        * }
        * */
    
        /**
         * 实现Runnable接口的run方法,这个方法称为线程执行体
         * */
        @Override
        public void run() {
            doSomething();
        }
    
        /**
         * 需要处理的任务
         * */
        private void doSomething(){
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "执行" + i);
            }
        }
    }

    方式二:匿名内部类

    public class Anonymous {
    
        /*
        * 创建步骤如下:
        * 匿名内部类本质上也是一个类实现了Runnable接口,重写了run方法,只不过这个类没有名字,直接作为参数传入Thread类
        *
        * 调用示例:
        * //开启10个线程
        * for (int i = 0; i < 10; i++) {
        *     Anonymous anonymous =new Anonymous();
        *     anonymous.myRun();
        * }
        *
        * */
    
        public void myRun(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    doSomething();
                }
            }).start();
        }
    
        /**
         * 需要处理的任务
         * */
        private void doSomething(){
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "执行" + i);
            }
        }
    }

    3,实现Callable接口

    public class CallableImpl implements Callable<String> {
    
        /*
         * 创建步骤如下:
         * 1,定义实现Callable<V>接口的实现类,实现call方法,这个方法是线程执行体
         * 2,创建Callable<V>实现类的实例,借助FutureTask得到线程执行的返回值
         * 3,将FutureTask的实例,作为Thread的target来创建Thread类
         * 4,调用start方法,开启线程
         *
         * 调用示例:
         * Callable<String> tc = new CallableImpl();
         * FutureTask<String> task = new FutureTask<>(tc);
         * new Thread(task).start();
         * try {
         *     System.out.println(task.get());
         * } catch (InterruptedException | ExecutionException e) {
         *     e.printStackTrace();
         * }
         *
         * 说明:
         * 1.与使用Runnable相比, Callable功能更强大些
         * 2.实现的call()方法相比run()方法,可以返回值
         * 3.方法可以抛出异常
         * 4.支持泛型的返回值
         * 5.需要借助FutureTask类,比如获取返回结果
         * Future接口可以对具体Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等。
         * FutureTask是Futrue接口的唯一的实现类
         * FutureTask 同时实现了Runnable, Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
         *
         * */
    
        private int ticket = 5;
    
        @Override
        public String call() throws Exception {
            for (int i = 0; i < 10; i++) {
                System.out.println(doSomething());
            }
    
            return "出票任务完成";
        }
    
        public String doSomething() {
            String result = "";
            if (this.ticket > 0) {
                result = "出票成功,ticket=" + this.ticket--;
            } else {
                result = "出票失败,ticket=" + this.ticket;
            }
            return result;
        }
    }

    4,创建线程池

    public class ThreadPool implements Runnable {
    
        /*
         * 创建步骤如下:
         * 1,定义Runnable接口的实现类,或者定义(继承Runnable接口的类)的实现类,并且实现run方法,这个方法是线程执行体
         * 2,创建一个自定义线程个数的线程池
         * 3,实例化Runnable接口的实现类
         * 4,将3步的实例,作为线程池实例的execute方法的command参数,开启线程
         * 5,关闭线程池
         *
         * 调用示例:
         * ExecutorService pool = Executors.newFixedThreadPool(2);
         * ThreadPool threadPool = new ThreadPool("AA");
         * ThreadPool threadPoo2 = new ThreadPool("BB");
         * pool.execute(threadPool);
         * pool.execute(threadPoo2);
         * pool.shutdown();
         *
         * 说明:
         * 示例中创建的是2个线程的线程池
         * execute方法是开启线程方法,实参要求是实现Runnable的类。所以,继承Thread类的子类也可以以线程池的方式开启线程
         *
         * */
    
        String name;
        public ThreadPool(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            doSomething();
        }
    
        /**
         * 需要处理的任务
         * */
        private void doSomething() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "执行" + i + ",name=" + this.name);
            }
        }
    }

    展开全文
  • 线程启动方法start()和run()

    千次阅读 2020-03-23 18:17:42
    因为thread线程有5种状态,创建-就绪-运行-阻塞-死亡这五种,用Thread类的start()方法启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,等到cpu空闲时,才会执行线程里面的run方法,run方法运行完毕...

    1.start
    使用start方法才真正实现了多线程运行,因为使用start()方法不用等待run方法体代码执行完毕而直接继续执行下面的代码。
    因为thread线程有5种状态,创建-就绪-运行-阻塞-死亡这五种,用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,等到cpu空闲时,才会执行线程里面的run方法,run方法运行完毕,此线程结束。

    2.run
    因为run方法是thread里面的一个普通的方法,直接调用run方法,这个时候它是会运行在我们的主线程中的,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到多线程的目的。

    代码示例:

    public class ThreadDemo {
        public static void main(String[] args){
            Thread thread1 = new Thread(new MyRunnable());
            Thread thread2 = new Thread(new MyRunnable());
            thread1.start();
            thread2.start();
        }
    }
    
    class MyRunnable implements Runnable {
    
        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println(i);
                    Thread.sleep(100);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    两个线程都是使用start方法开启的,所以并不需要等待另一个完成,所以他们的执行顺序应该是并行的,我们运行看一下结果:
    在这里插入图片描述
    和我们分析的一样,那么我们改改代码,执行使用run方法,看看是否顺序执行

     public static void main(String[] args){
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());
        thread1.run();
        thread2.run();
    }
    

    在这里插入图片描述
    总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。

    展开全文
  • Thread 和 启动线程几种方式

    千次阅读 2019-02-15 10:20:09
    启动线程几种方式第一种: 1】d定义Thread类的子类,并重写...3】启动线程,即调用线程的start()方法 注:(start ()是真正的启用了线程 run() 只是thread类的一个方法) 第二种: A类实现runnable 重写run 方...
  • java开启新线程的三种方法方法1:继承Thread类 ...4):在main方法(线程)中,创建一个线程对象并启动线程。 (1)创建线程类对象: A类 a = new A类(); (2)调用线程对象的start方法: a.start();...
  • Java创建并执行线程的四种方法

    千次阅读 2021-10-01 18:28:40
    Java创建并执行线程的四种方法 java里面创建线程有四种方式: 无返回: 实现Runnable接口,重写run(); 继承Thread类,重写run(); 有返回: 实现Callable接口,重写call(),利用FutureTask包装Callable,并作为task...
  • 本篇来统一解答一下java启动线程方法。 java怎么启动线程池? Java中创建线程有四种方式,我们下面依次介绍一下。 1、继承 Thread 类 (1)定义Thread类的子类,并重写该类的run方法,该run方法方法体就代表...
  • Java启动线程两种方式总结

    千次阅读 2018-07-12 14:40:48
    先查看jdk帮助文档,这么进行描述线程线程是程序中的执行线程,可以由jvm来运行一个或者多个线程方法1:继承Thread 类 重写run方法即可 如下代码: public class Treadtest { //主方法 public static...
  • Android 中三种启用线程方法

    千次阅读 2021-12-03 09:33:55
    1.start()方法启动线程,真正实现了多线程运行。 这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码 通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行 然后...
  • Java线程篇---两种构建线程方法

    千次阅读 2021-12-16 10:59:03
    Java线程的创建及线程安全的解决,定时器的使用
  • 创建和启动线程的两种方式

    万次阅读 多人点赞 2016-10-07 10:52:48
    方式1:继承Thread类 步骤: 1):定义一个类A继承于java.lang.Thread类. 2):在A类中覆盖Thread类中的run方法. ...4):在main方法(线程)中,创建线程对象,并启动线程. (1)创建线程类对象: A类 a = new A类();
  • java线程的常用方法

    千次阅读 2021-03-06 01:13:58
    java线程的常用方法编号方法说明1public void start()使该线程开始执行;Java 虚拟机调用该线程的 run 方法。2public void run()如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run ...
  • 1):定义一个类A继承于Java.lang.Thread类.2):在A类中覆盖Thread类中的run方法.3):我们在run方法中编写需要执行的操作:run方法里的代码,线程执行.4):在main方法(线程)中,创建线程对象,并启动线程.(1)创建线程类...
  • 创建启动线程的两种方式

    千次阅读 2018-04-08 21:00:03
    方式一:继承Thread类;步骤:1)定义一个类 A继承于java.lang.Thread类;2)在A类中覆盖Thread...4)在main方法(线程)中,创建线程对象,并启动线程。创建线程类对象: A类 a = new A类( );调用线程对象的start...
  • 1):定义一个类A继承于Java.lang.Thread类.2):在A类中覆盖Thread类中的run方法.3):我们在run方法中编写需要执行的操作:run方法里的代码,线程执行.4):在main方法(线程)中,创建线程对象,并启动线程:(1)创建线程类...
  • 开启线程的三种方式?

    千次阅读 2019-07-25 13:05:58
    一、继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类...(3)调用线程对象的start()方法启动线程。 二、通过Runnable接口创建线程类 (1)定义runnable接口的实现类,并重写该接口的run()方法...
  • 用start方法启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦...
  • java之内部类中启动线程

    千次阅读 2017-12-22 09:28:29
    2 如果想要在内部类中启动线程。并调用它。则和在方法体中启动一个线程差不多。不过该方法是内部类中的方法。传递的参数为list类型最好。 如:public class TestNeibuleiThread { public void test(){ ...
  • 为什么不能直接调用run( )方法,而必须调用start()方法开启一个线程? 如果一个线程的start()方法内部调用run()方法,那么为什么我们不直接在我们的代码中调用run()方法呢?这样做有什么问题? 1.start方法确保代码在...
  • java多线程之启动线程的三种方式

    万次阅读 多人点赞 2018-08-12 14:42:08
    java对多线程有着良好的支持,java创建和启动线程较为常用的方式有继承Thread类、实现Runnable接口和匿名内部类的方式。 1.继承Thread类: 通过继承Thread类来创建并启动多线程步骤如下: 1、定义Thread类的子类...
  • * 在 Java中启动线程调用的是start方法。* 在start方法中,真正实现多线程的是一个本地的方法start0。* 调用start方法启动一个线程,此时的状态是 就绪。* 无需等待run方法体代码执行完毕,可以继续执行下面的代码...
  • 结论:启动线程,如果对target进行赋值,并且没有重写run方法,则线程start的时候会直接调用target中对应的方法 具体代码如下: 1、初始化一个线程 threading.Thread.__init__(self,target=thread_run()) def __...
  • 1、多线程的创建注意:线程开启不一定立即执行,由CPU调度执行1.1创建方式一继承Thread类,...public class Thread_01 extends Thread{@Overridepublic void run() {//run方法线程体for (int i = 0; i < 20; i++)...
  • Java中启动线程start和run方法的区别

    千次阅读 2015-10-01 10:59:25
    Java中启动线程有两种方式,继承Thread类以及实现接口Runnable,由于Java无法... start():通过该方法启动线程的同时也创建了一个线程,真正实现了多线程,这是无需等待run()方法中的代码执行完毕就可以直接执行下面
  • Android面试之线程同步的方法

    千次阅读 2021-12-06 11:39:58
    进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间...
  • 线程相关方法详解

    万次阅读 2018-04-18 11:01:29
      用start() 方法启动线程,真正实现了多线程运行,这时无需等待run() 方法内代码执行完毕,而是直接继续执行下面的代码。通过start()方法启动一个线程后,线程处于就绪状态,并没有运行,一旦得到CPU时间片,就...
  • C++线程同步——阻塞线程方法

    千次阅读 2021-08-29 21:09:05
    sem_wait() 会阻塞当前线程 sem_trywait() 返回错误而不是阻塞调用 sem_timedwait() sem_timedwait的abs_timeout参数指定了调用应该阻塞的时间限制 信号量 信号量 (semaphore) 是一种轻量的同步原件,用于制约对...
  • 关于java启动线程

    2022-01-05 10:19:07
    第一种方法 第一种方式:编写一个类,直接继承java.lang.Thread,... 怎么启动线程呢? 调用线程对象的start()方法。 注意: 亘古不变的道理: 方法体当中的代码永远都是自上而下的顺序依次逐行执行的。 以下程序
  • 实现并启动线程有两种方法 1、写一个类继承自Thread类,重写run方法。用start方法启动线程 2、写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动多线程原理:相当于玩游戏机...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 115,095
精华内容 46,038
热门标签
关键字:

启动线程体的方法