精华内容
下载资源
问答
  • 文章目录创建线程的四种方式区别示例 创建线程的四种方式 1:继承Thread类创建线程 2:实现Runnable接口创建线程 3:使用CallableFutureTask创建线程 4:使用线程池,例如用Executor框架创建线程 区别 1、...

    创建线程的四种方式

    • 1:继承Thread类创建线程

    • 2:实现Runnable接口创建线程

    • 3:使用Callable和FutureTask创建线程

    • 4:使用线程池,例如用Executor框架创建线程

    区别

    1、使用继承Thread类的方式创建多线程

    • 因为java单继承的机制无法再继承其他的类

    • 直接使用this即可获得当前线程

    2、实现Callable和Runnable创建多线程

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

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

    3、Callable和Runnable的区别

    相同点:

    1. 两者都是接口

    2. 两者都需要调用Thread.start启动线程

    不同点:

    1. callable的核心是call方法,允许返回值,runnable的核心是run方法,没有返回值

    2. call方法可以抛出异常,但是run方法不行

    3. 因为runnable是java1.1就有了,所以他不存在返回值,后期在java1.5进行了优化,就出现了callable,就有了返回值和抛异常

    4. callable和runnable都可以应用于executors。而thread类只支持runnable

    示例

    /**
     * CreateThreadTest
     *
     * @author xgSama
     * @date 2021/1/19 11:46
     */
    public class CreateThreadTest {
    
        public static void main(String[] args) throws Exception {
            // 方式一:继承Thread
            MyThread thread1 = new MyThread();
            thread1.start();
            
            // 方式二:实现Runable
            Thread thread2 = new Thread(new MyRunnable());
            thread2.start();
            
            // 方式三:实现Callable
            Callable<Integer> callable = new MyCallable();
            FutureTask<Integer> futureTask = new FutureTask<>(callable);
            Thread thread3 = new Thread(futureTask);
            thread3.start();
            Integer integer = futureTask.get();
            System.out.println(integer);
            
            // 方式四:线程池
            ExecutorService es = Executors.newFixedThreadPool(5);
            for (int i = 0; i < 5; i++) {
                es.execute(() ->
                     System.out.println(Thread.currentThread() + "created by Executors"));
            }
            es.shutdown();  
        }
    
    
    }
    
    // 方式一、继承Thread类,重写run方法
    class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread() + "created by Thread");
        }
    }
    
    // 方二、实现Runnable接口,重写run方法,将实现类的实例对象作为Thread构造函数的target创建并启动线程
    class MyRunnable implements Runnable {
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread() + "created by Runnable");
        }
    }
    
    // 方式三、实现Callable接口,使用FutureTask类包装Callable对象,使用FutureTask对象作为Thread对象的target创建并启动线程
    class MyCallable implements Callable<Integer> {
    
        @Override
        public Integer call() {
            System.out.println(Thread.currentThread() + "created by Callable ");
            return 666;
        }
    }
    
    
    展开全文
  • java中创建线程的三种方法以及区别 Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用三种方式来创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable...

    Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用三种方式来创建线程,如下所示:

    1)继承Thread类创建线程

    2)实现Runnable接口创建线程

    3)使用Callable和Future创建线程

    下面让我们分别来看看这三种创建线程的方法。

    ------------------------继承Thread类创建线程---------------------

    通过继承Thread类来创建并启动多线程的一般步骤如下

    1】d定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。

    2】创建Thread子类的实例,也就是创建了线程对象

    3】启动线程,即调用线程的start()方法

    代码实例

    public class MyThread extends Thread{//继承Thread类
    
      public void run(){
    
      //重写run方法
    
      }
    
    }
    
    public class Main {
    
      public static void main(String[] args){
    
        new MyThread().start();//创建并启动线程
    
      }
    
    }
    

    ------------------------实现Runnable接口创建线程---------------------

    通过实现Runnable接口创建并启动线程一般步骤如下:

    1】定义Runnable接口的实现类,一样要重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体

    2】创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象

    3】第三部依然是通过调用线程对象的start()方法来启动线程

    代码实例:

    public class MyThread2 implements Runnable {//实现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();
    
      }
    
    }
    

    ------------------------使用Callable和Future创建线程---------------------

    和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。

    》call()方法可以有返回值

    》call()方法可以声明抛出异常

    Java5提供了Future接口来代表Callable接口里call()方法的返回值,并且为Future接口提供了一个实现类FutureTask,这个实现类既实现了Future接口,还实现了Runnable接口,因此可以作为Thread类的target。在Future接口里定义了几个公共方法来控制它关联的Callable任务。

    boolean cancel(boolean mayInterruptIfRunning):视图取消该Future里面关联的Callable任务

    V get():返回Callable里call()方法的返回值,调用这个方法会导致程序阻塞,必须等到子线程结束后才会得到返回值

    V get(long timeout,TimeUnit unit):返回Callable里call()方法的返回值,最多阻塞timeout时间,经过指定时间没有返回抛出TimeoutException

    boolean isDone():若Callable任务完成,返回True

    boolean isCancelled():如果在Callable任务正常完成前被取消,返回True

    介绍了相关的概念之后,创建并启动有返回值的线程的步骤如下:

    1】创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。

    2】使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值

    3】使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)

    4】调用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;
    
        }
    
        );
    
       new Thread(task,"有返回值的线程").start();//实质上还是以Callable对象来创建并启动线程
    
        try{
    
        System.out.println("子线程的返回值:"+future.get());//get()方法会阻塞,直到子线程执行结束才返回
    
        }catch(Exception e){
    
        ex.printStackTrace();
    
       }
    
      }
    
    }
    

    --------------------------------------三种创建线程方法对比--------------------------------------

    实现Runnable和实现Callable接口的方式基本相同,不过是后者执行call()方法有返回值,后者线程执行体run()方法无返回值,因此可以把这两种方式归为一种这种方式与继承Thread类的方法之间的差别如下:

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

    2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。

    3、但是编程稍微复杂,如果需要访问当前线程,必须调用Thread.currentThread()方法。

    4、继承Thread类的线程类不能再继承其他父类(Java单继承决定)。

    注:一般推荐采用实现接口的方式来创建多线程

    另一篇专门介绍callable方式的文章,复制如下:
    Callable和Future出现的原因
    创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。
    这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
    如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。

    而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。
    Callable和Future介绍
    Callable接口代表一段可以调用并返回结果的代码;Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。

    Callable接口使用泛型去定义它的返回类型。Executors类提供了一些有用的方法在线程池中执行Callable内的任务。由于Callable任务是并行的(并行就是整体看上去是并行的,其实在某个时间点只有一个线程在执行),我们必须等待它返回的结果。
    java.util.concurrent.Future对象为我们解决了这个问题。在线程池提交Callable任务后返回了一个Future对象,使用它可以知道Callable任务的状态和得到Callable返回的执行结果。Future提供了get()方法让我们可以等待Callable结束并获取它的执行结果。

    Callable与Runnable
    java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法:

    public interface Runnable {
        public abstract void run();
    }
    

    由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。

    Callable位于java.util.concurrent包下,它也是一个接口,在它里面也只声明了一个方法,只不过这个方法叫做call():

    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()函数返回的类型就是传递进来的V类型。

    那么怎么使用Callable呢?
    一般情况下是配合ExecutorService来使用的,在ExecutorService接口中声明了若干个submit方法的重载版本:

    Future submit(Callable task);
    Future submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    第一个submit方法里面的参数类型就是Callable。

    暂时只需要知道Callable一般是和ExecutorService配合来使用的,具体的使用方法讲在后面讲述。

    一般情况下我们使用第一个submit方法和第三个submit方法,第二个submit方法很少使用。

    Future
      Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。

    Future类位于java.util.concurrent包下,它是一个接口:

    public interface Future<V> {
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
        V get() throws InterruptedException, ExecutionException;
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }
    

    在Future接口中声明了5个方法,下面依次解释每个方法的作用:
    cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。

    isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。

    isDone方法表示任务是否已经完成,若任务完成,则返回true;

    get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;

    get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。

    也就是说Future提供了三种功能:
      1)判断任务是否完成;

    2)能够中断任务;

    3)能够获取任务执行结果。

    因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。

    FutureTask
    FutureTask实现了RunnableFuture接口,这个接口的定义如下:

    public interface RunnableFuture<V> extends Runnable, Future<V> {  
        void run();  
    }  
    

    可以看到这个接口实现了Runnable和Future接口,接口中的具体实现由FutureTask来实现。这个类的两个构造方法如下 :

    public FutureTask(Callable<V> callable) {  
            if (callable == null)  
                throw new NullPointerException();  
            sync = new Sync(callable);  
        }  
        public FutureTask(Runnable runnable, V result) {  
            sync = new Sync(Executors.callable(runnable, result));  
        }  
    

    如上提供了两个构造函数,一个以Callable为参数,另外一个以Runnable为参数。这些类之间的关联对于任务建模的办法非常灵活,允许你基于FutureTask的Runnable特性(因为它实现了Runnable接口),把任务写成Callable,然后封装进一个由执行者调度并在必要时可以取消的FutureTask。

    FutureTask可以由执行者调度,这一点很关键。它对外提供的方法基本上就是Future和Runnable接口的组合:get()、cancel、isDone()、isCancelled()和run(),而run()方法通常都是由执行者调用,我们基本上不需要直接调用它。

    一个FutureTask的例子

    public class MyCallable implements Callable<String> {  
        private long waitTime;   
        public MyCallable(int timeInMillis){   
            this.waitTime=timeInMillis;  
        }  
        @Override  
        public String call() throws Exception {  
            Thread.sleep(waitTime);  
            //return the thread name executing this callable task  
            return Thread.currentThread().getName();  
        }  
    
    }  
    public class FutureTaskExample {  
         public static void main(String[] args) {  
            MyCallable callable1 = new MyCallable(1000);                       // 要执行的任务  
            MyCallable callable2 = new MyCallable(2000);  
    
            FutureTask<String> futureTask1 = new FutureTask<String>(callable1);// 将Callable写的任务封装到一个由执行者调度的FutureTask对象  
            FutureTask<String> futureTask2 = new FutureTask<String>(callable2);  
    
            ExecutorService executor = Executors.newFixedThreadPool(2);        // 创建线程池并返回ExecutorService实例  
            executor.execute(futureTask1);  // 执行任务  
            executor.execute(futureTask2);    
    
            while (true) {  
                try {  
                    if(futureTask1.isDone() && futureTask2.isDone()){//  两个任务都完成  
                        System.out.println("Done");  
                        executor.shutdown();                          // 关闭线程池和服务   
                        return;  
                    }  
    
                    if(!futureTask1.isDone()){ // 任务1没有完成,会等待,直到任务完成  
                        System.out.println("FutureTask1 output="+futureTask1.get());  
                    }  
    
                    System.out.println("Waiting for FutureTask2 to complete");  
                    String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);  
                    if(s !=null){  
                        System.out.println("FutureTask2 output="+s);  
                    }  
                } catch (InterruptedException | ExecutionException e) {  
                    e.printStackTrace();  
                }catch(TimeoutException e){  
                    //do nothing  
                }  
            }  
        }  
    }  
    

    运行如上程序后,可以看到一段时间内没有输出,因为get()方法等待任务执行完成然后才输出内容.

    输出结果如下:
    FutureTask1 output=pool-1-thread-1
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    Waiting for FutureTask2 to complete
    FutureTask2 output=pool-1-thread-2
    Done

    展开全文
  • 线程(thread)是操作系统能够进行运算调度最小单位。它被包含在进程之中,是进程中实际运作单位。一条线程是进程中一个单一顺序控制流,一个进程中可以并发多个线程,每条线程并行执行不同任务。同一...

    线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。同一进程中的多条线程将共享该进程中的全部系统资源。



    源码浅析

    Runnable源码

    Runnable是个空接口,只有一个抽象方法run()

    @FunctionalInterface
    public interface Runnable {
    
        public abstract void run();
    }
    
    Thread源码截取

    Thread类是线程运行的入口;
    通过start()方法唤醒线程;

    public class Thread implements Runnable {
      /* What will be run. */
        private Runnable target;		//rannable参数
        
    	public Thread() {
    	        init(null, null, "Thread-" + nextThreadNum(), 0);
    	    }
    	    
    	public Thread(Runnable target) {
    	        init(null, target, "Thread-" + nextThreadNum(), 0);
    	    }
    
     	@Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }
    }
    

    分析

    Tread.start()会唤醒线程,随后线程会执行自己的run方法;
    跟踪源码我发现;start()调用了一个native方法start0()
    所以start()是如何调用run()的,我们无从得知了;

    回到run()方法上
    target是Thread类的Runnable属性;
    如果Thread对象持有一个Runnable实现类的对象,
    这里调用的就是该对象的run方法;

    	@Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }
    


    从Tread类到创建多线程

    Java中有2种创建多线程的方式:

    1、继承Thread类

    继承Thread类,重写了run方法,则执行的是Thread子类的run方法;
    Thread子类

    public class TestThread extends Thread{
        @Override
        public void run() {
              System.out.println('继承Thread类');
        }
    }
    
    Tread t=new TestThread ();
    t.start();
    
    2、实现Runable接口

    实现Runable接口,创建Thread对象时传入Runnable的实现类,则执行的是该实现类的run方法;
    Rannable接口实现类

    public class TestRunnable implements Runnable{
        @Override
        public void run() {
                System.out.println('实现Runable接口');
        }
    }
    
    TestRunnable  runnable=new TestRunnable();
    Tread t=new Thread(runnable);
    t.start();
    

    无论是哪种方法,切入点都是Thread类,区别是:

    继承Thread类的顺序是:
    Thread.start()→Thread.run()

    实现Runable接口顺序是:
    Thread.start()→Thread.run()→Runable.run()

    所以说Thread类是线程的入口;



    其他

    匿名内部类 方式

    调用Thread有参构造器,传入一个Runnable实例;
    (Runnable是接口,所以这里要求重写它的所有方法;)

      new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("匿名内部类方式");
                    }
                }).start();
    
    lambda表达式 方式
                new Thread(()-> {
                    System.out.println("lambda表达式方式");
            }).start();
    
    展开全文
  • Java 提供了三种创建线程的方法: 通过实现 Runnable 接口; 通过继承 Thread 类; 通过 Callable Future 创建线程。 这里只介绍两种第一种第二种。   1.以创建Runnable接口实例的方式创建线程 public ...

    创建一个线程

    Java 提供了三种创建线程的方法:

    • 通过实现 Runnable 接口;
    • 通过继承 Thread 类;
    • 通过 Callable 和 Future 创建线程。

    这里只介绍两种第一种和第二种。

     

    1.以创建Runnable接口实例的方式创建线程

    public class WelcomApp1 {
    	public static void main(String[] args) {
    		//创建线程
    		Thread welcomThread = new Thread(new WelcomTask());
    		//启动线程
    		welcomThread.start();
    		System.out.printf("welcom2! I'm %s.%n",Thread.currentThread().getName());
    	}
    	
    }
    class WelcomTask implements Runnable{
    	//在run方法中实现处理线程任务的逻辑
    	public void run() {
    		System.out.printf("Welocm1!I'm !%s.%n",Thread.currentThread().getName());
    	}
    }

    2.定义Thread类的子类方式创建线程 

    public class WelcomApp {
    	public static void main(String[] args) {
                    //创建线程
    		Thread welcomThread = new WelcomThread();
                    //启动线程
    		welcomThread.start();
    		System.out.printf("welcom2! I'm %s.%n",Thread.currentThread().getName());
    	}
    }
    //定义Thread类的子类class WelcomThread extends Thread{
    	//在run()方法中实现业务逻辑
    	public void run(){
    		System.out.printf("Welocm1!I'm !%s.%n",Thread.currentThread().getName());
    	}
    }

    线程两种创建方式的区别:
     (1)从面向对象编程的角度来看,创建Thread类的子类是一种基于继承的技术,第一种实现Runnable接口(以实现Runnable接口 实例为构造器参数直接通过new创建Thread实例)是一种基于组合(Composition)的技术。由于组合相对于继承来说,其类与类之间的耦合性(Couping)更低,因此,它也更加的灵活,即,优先使用组合。

    (2)从对象共享的角度来看:第一种创建方式以意味着多个线程实例可以共享同一个Runnable实例。

    (3)从对象创建成本来看:JAVA中的线程实例是一个“特殊”Runnable实例,因为在创建它的时候JAVA虚拟机会为其分配调用栈空间、内核线程等资源。因此,创建一个线程实例比起创建一个普通的Runnable实例来说,其成本要相对昂贵一点。所以,如果创建Runnable实例在将其作为方法参数传递给其他对象使用而不必用它来创建相应的线程,既可以满足我们的计算需要,也不需要创建线程实例。

    展开全文
  • 导读热词在java中如果要创建线程的话,一般有3种方法:继承Thread类;实现Runnable接口;使用CallableFuture创建线程。1. 继承Thread类继承Thread类的话,必须重写run方法,在run方法中定义需要执行的任务。...
  • 线程和进程区别 进程:是系统进行分配管理资源基本单位 线程:进程一个执行单元,是进程内调度实体、是CPU调度分派基本单位,是比进程更小独立运行基本单位。线程也被称为轻量级进程,线程是程序执行...
  • 线程的创建两种方式和区别

    千次阅读 2012-12-31 14:58:32
    创建线程的一种方式是:继承Thread类,并复写类中run方法 最后调用线程的start方法, 该方法启动线程并调用run方法(即模板方法类似) getName();获取线程的名称 static Thread currentThread()为获取当前线程对象 ...
  • 通过使用Callable创建线程的方式本文中不在讨论,可以参考:http://blog.csdn.net/dax1n/article/details/60322067 方式1: 实现Runnable接口创建线程 public class RunnableDemo implements Runnable { @...
  • 1.创建线程的两种方式区别 采用继承Thread类方式: (1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。 (2)缺点:因为线程类已经继承了Thread...
  • 那么这两种实现多线程的方式在应用上有什么区别呢?   为了回答这个问题,我们可以通过编写一段代码来进行分析。我们用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一...
  • 2.重写Thread类中的run方法(自定义线程的任务代码就放在run方法里); 3.创建Thread子类的对象,并且调用start方法开启线程,(run方法不能直接调用) 示例: class Demo extends Thread{ public void run...
  • 线程的创建方式有两种 1.继承Thread类 2.实现Runnable接口Thread与Runnable的区别: 1、继承Thread类无法达到资源共享的目的,而实现Runnable可以让多个相同程序代码线程去处理统一资源的情况,把虚拟的cpu(线程...
  • Java可以用三种方式创建线程: 1、继承Thread类创建线程 2、实现Runnable接口创建线程 3、使用CallableFuture创建线程 1、继承Thread类创建线程 通过继承Thread类来创建并启动多线程的一般步骤如下 1、定义...
  • Java 提供了三种创建线程的方法 通过实现Runnable接口 通过继承Thread接口 通过CallableFuture创建线程 通过实现 Runnable 接口来创建线程 public class RunnableDemo { public static void main...
  • 前言:看到很多博客上都写过多线程的实例以及这两种方式区别,其中让我报有疑惑的一点是很多都说继承Thread而实现的多线程无法共享资源?我自己下来敲了敲,再结合一些资料做了如下总结 先创建了两个类,一个是...
  • java创建线程的两种方式区别

    千次阅读 2018-07-24 18:35:47
    本文将介绍创建线程的两种方式,示例代码在下面,复制粘贴即可 继承Thread类方式和实现Runnable接口方式 区别:由于在开发的过程中,很多的类都会用到继承的方式,如果采用继承的方式会让各个类之间的关系变得错综...
  • 文章目录1、创建线程的三种方式2、runnablecallable的区别 1、创建线程的三种方式 2、runnablecallable的区别
  • 今天面试时候被问到这个...第一种创建方式:继承Thread,并且重写run方法。[java] view plain copypackage com.easytopit.thread; public class ExtendsThread extends Thread { @Override public v...
  • 创建线程的方式

    2019-03-07 11:07:21
    初识java多线程概述初识多线程线程的两种创建方式多线程会出现的线程不安全问题认识synchronizedvolatile关键字java线程抽象内存模型volatile关键字的作用synchronized关键字的作用volatile关键字synchronized...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,111
精华内容 844
关键字:

创建线程的方式和区别