线程并发学习----Thread、Runnable、Callable

来源:互联网 发布:linux只读文件怎么修改 编辑:程序博客网 时间:2024/05/17 05:08

线程并发学习

线程并发学习—-核心概念(转载)
线程并发学习—-线程阻塞(sleep、wait、notifyAll、notify、join)
线程并发学习—-线程阻塞(synchronized)
线程并发学习—-线程阻塞(lock)
线程并发学习—-Thread、Runnable、Callable
线程并发学习—-队列(Queue)
spring学习—-线程池
java中一些锁概念整理(转载)

线程简介

线程状态转换图(网上load)

这里写图片描述

线程状态介绍

  • 新建状态(New):新创建了一个线程对象。
  • 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
  • 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
  • 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

    阻塞的情况分三种:
    (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
    (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
    (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

  • 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

java中多线程实现

继承Thread

例子

//继承Thread类public class ThreadDemo extends Thread{    //实现Thread类run方法    @Override    public void run(){        System.out.println("这是线程的run方法");    }    public static void main(String[] args) {        ThreadDemo threadDemo = new ThreadDemo();        //启动线程,为什么是start 不是run见源码        threadDemo.start();    }}

实现Runnable

例子

public class RunnableDemo implements Runnable {    @Override    public void run() {        System.out.println("这是实现Runnable的run方法1");    }    public static void main(String[] args) {        //实现Runnable接口实现        new Thread(new RunnableDemo()).start();        //匿名内部类实现        new Thread(new Runnable(){            @Override            public void run() {                System.out.println("这是实现Runnable的run方法2");            }        }).start();    }}

实现Callable

例子

public class CallableDemo implements Callable<String>{    @Override        public String call() throws Exception {        System.out.println("这是Callable的call方法");        return "success";    }    public static void main(String[] args) throws Exception{        CallableDemo callableDemo = new CallableDemo();        ExecutorService exec = Executors.newCachedThreadPool();        ArrayList<Future<String>> results = new ArrayList();    //Future 相当于是用来存放Executor执行的结果的一种容器        for (int i = 0; i < 10; i++) {            results.add(exec.submit(new CallableDemo()));        }        for (Future<String> fs : results) {            if (fs.isDone()) {                System.out.println(fs.get());            } else {                System.out.println("Future result is not yet complete");            }        }        exec.shutdown();    }}

三种方式分析

继承Thread实现简单,但有局限性java的类只能继承一个父类(一般不会使用)
实现接口更灵活,避免继承的局限,可以实现多个接口

实现Runnable与Callable大体一样,区别

  • Runnable使用run()方法,Callable使用call()方法
  • run方法没有返回值,call方法有返回值
  • run不能抛出受检查异常 ,call可以抛出受检查异常。如:ClassNotFoundException

Runnable通过Thread包装实现 或者 FutureTask包装实现
Callable一般通过ExecutorService包装,本质是通过FutureTask实现

java线程类图分析

这里写图片描述

ThreadPoolExecutor的execute方法参数只能为Runnable
AbstractExecutorService的submit方法可以将Runnable和Callable包装为FutureTask,再调用execute方法

FutureTask实现RunnableFuture实现Runnable接口

ThreadPoolExecutor的execute方法,addWorker—》Worker—》默认使用DefaultThreadFactory—》new Thread—》执行start方法启动线程,执行FutureTask的run方法

详情见http://blog.csdn.net/eos2009/article/details/78617618的源码 AbstractExecutorService

自己的理解:java线程的本质 Thread 的start创建线程,执行run方法实现

源码

Thread

//Thread 实现Runnable接口public class Thread implements Runnable {public synchronized void start() {        if (threadStatus != 0)            throw new IllegalThreadStateException();        group.add(this);        boolean started = false;        try {            //通过调用底层start0方法创建执行线程            start0();            started = true;        } finally {            try {                if (!started) {                    group.threadStartFailed(this);                }            } catch (Throwable ignore) {                /* do nothing. If start0 threw a Throwable then                  it will be passed up the call stack */            }        }    }    //操作系统底层函数    private native void start0();

FutureTask

    public FutureTask(Callable<V> callable) {        if (callable == null)            throw new NullPointerException();        this.callable = callable;        this.state = NEW;       // ensure visibility of callable    }    //将runnable任务包装为callable 使其有返回值  使用Executors工具类    public FutureTask(Runnable runnable, V result) {        this.callable = Executors.callable(runnable, result);        this.state = NEW;       // ensure visibility of callable    }

Executors

//public static <T> Callable<T> callable(Runnable task, T result) {        if (task == null)            throw new NullPointerException();        return new RunnableAdapter<T>(task, result);    }static final class RunnableAdapter<T> implements Callable<T> {        final Runnable task;        final T result;        RunnableAdapter(Runnable task, T result) {            this.task = task;            this.result = result;        }        public T call() {            //底层实现使用Runnable接口run方法            task.run();            return result;        }    }

参考资料

http://blog.csdn.net/pcceo1/article/details/52444730

阅读全文
0 0