JAVA多线程学习(1) 创建线程基础知识

整体大图

JAVA多线程学习是javaer的一大难关,博主也在其中绕了又绕,看了又看,看完又忘,忘了再看,看了再忘,如此反复,不得其要,所以决定写这个多线程学习的系列博客,刨根问底,习得精髓。

构思了一下,画了下面的XMIND图,整个系列化会按照这个图来写,如果有更好的图结构,欢迎大家指点。

JAVA多线程学习(1) 创建线程基础知识_第1张图片

线程的基础知识

关于线程和进程的区别我就不多复述了,给大家贴一个百度链接

https://baike.baidu.com/item/%E7%BA%BF%E7%A8%8B/103101?fr=aladdin

创建线程的几种方式

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable 接口

前两条都是大家熟知的线程创建方式,但是第三条可能不太熟悉,看下javadoc

package java.util.concurrent;

/**
 * A task that returns a result and may throw an exception.
 * Implementors define a single method with no arguments called
 * {@code call}.
 *
 * 

The {@code Callable} interface is similar to {@link * java.lang.Runnable}, in that both are designed for classes whose * instances are potentially executed by another thread. A * {@code Runnable}, however, does not return a result and cannot * throw a checked exception. * *

The {@link Executors} class contains utility methods to * convert from other common forms to {@code Callable} classes. * * @see Executor * @since 1.5 * @author Doug Lea * @param the result type of method {@code call} */ @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; }

 A task that returns a result and may throw an exception.

其实第一句就说明了Callable和其他实现方式的不同之处,Callable是可以带有返回值的并且可能会抛出异常

如同其他实现方式一样,Callable接口也有一个执行的方法那就是call方法

  /**
     * 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;

计算结果或者抛出一个异常,其中V代表要返回结果的类型。

使用Callable来创建线程

使用thread和runnable创建线程这里就不多写了,主要看下callable是如何创建线程的

  1. 实现Callable接口 返回类型为String

public class Call implements Callable<String>{

        @Override
        public String call() throws Exception {
            return "这是一个callable线程执行的结果";
        }
    }
  1. 使用FutureTask包裹Callable实现
	 Call call = new Call();
	 FutureTask<String> task = new FutureTask<>(call);
  1. 使用Thread类包装FutureTask,并且启动线程
	 Thread thread = new Thread(task);
	 thread.start();
  1. 获取执行结果 (使用FuntureTask::get方法获取)
 	 String s = task.get();
	 System.out.println(s);

暂且不管FutureTask类是个什么鬼,在后续篇章会写到。

Callable接口和Runnable接口的区别

Callable接口和Runnable接口最大的区别其实在上面已经写到了

其他实现方式的不同之处,Callable是可以带有返回值的并且可能会抛出异常

  1. Callable带有返回值
  2. Callable可以抛出异常

再看下call方法

  /**
     * 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,并且会throws Exception

再看下Runable的run方法

/**
     * When an object implementing interface Runnable is used
     * to create a thread, starting the thread causes the object's
     * run method to be called in that separately executing
     * thread.
     * 

* The general contract of the method run is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run();

没有返回值,并且不会抛出异常,也就是说即使run内部有异常,那么也不会被catch到

总结

  1. 创建线程的方式有三种:
    		1. 继承Thread类,重写run方法
    		2. 实现Runnable接口,重写run方法
    		3. 实现Callable接口,实现call方法
    
  2. Callable和Runnable接口的区别
     	   1. callable接口有返回值
     	   2. callable接口可抛出异常
    

你可能感兴趣的:(多线程)