线程相关概念:
- 并发:在一段时间内,两个或以上的任务交替执行;并发不是同时执行,只是在很短的时间内看起来像是同时执行,例如:一个core的n个线程处理器可以并发执行任务,但是不能并行执行任务
- 并行:在同一时刻,两个或以上的任务同时执行;并行是真正的同时执行,n个core的处理器能够同时处理n个任务
- 临界区:访问共享资源的代码
- 同步:是指代码按照一条路线顺序执行
- 异步:代码按照多条线路执行,最终执行的结果因任务和CPU实际执行时间而异
1.线程介绍
- CPU的性能每18月翻倍的摩尔定律由单核心的提升变为了多核心的性能提升,为了充分发挥CPU多核心的优势,在IO密集型的任务里使用多线程是个不错的选择。
- 线程是进程内的执行单元,可以类比于函数,都有自己的栈空间和程序计数器,又能用到共享的堆内存;但不同的是,thread可以很好的发挥CPU多个核心的优势,同时执行多个任务,这是函数做不到的;不过多线程的创建与销毁、线程切换也会带来时间和空间上的开销。
2.Java单线程
- Runnable接口:通过实现Runnalbe接口,并重载run方法,通过调用该run方法来启动该线程,run方法的函数原型:
1 public void run();
由于返回值类型为void,导致我们不能通过实现Runnable接口来获得线程执行的返回值
- Thread类:Thread类也是是实现了Runnable接口,相同而是我们同样要重写run方法,不同的是要调用该类的start()方法来启动线程
- Callable接口:Runable接口有自身的缺陷:不能获得线程执行的返回值。通过实现Callable泛型接口重写call方法,可以获得线程的返回值。call的函数原型:
V call() throws Exception;
其中V是函数的泛型类型参数
3.Java线程池
- Executors类:Executors能够创建管理多个线程的线程池,不但方便开发者,而且能减少频繁手动创建、销毁线程带来的开销
1 ExecutorService service = Executors.newCachedThreadPool(); 2 service.execute(new ThreadTask());
Executors维护了通用的能够创建任意数目的cachedThreadPool,还维护了FixedThreadPool这样具有优先数目的线程池,使用FixedThreadPool,我们不必担心有多余的线程创建,当执行的任务数量超过线程数目时,该线程池管理器会等到部分任务结束继续执行后面的未执行的任务,也就是线程数目是由初始化的线程数来决定的。
- Future类:Executors管理的线程是由Callable泛型接口实现的时候,必须通过Future类的get方法来获得call()函数的返回值
1 ExecutorService service = Executors.newCachedThreadPool(); 2 Future future; 3 try { 4 future = service.submit(new Ctask()); 5 System.out.println(future.get()); 6 } catch (Exception e) { 7 //TODO: handle exception 8 }
4.共享
- synchronized
- volatile
- ThreadLocal
5.协作
- wait与notify
- 生产者与消费者
- 显示lock与condition
- 阻塞队列
- 栅栏