`
hesihua
  • 浏览: 228730 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
社区版块
存档分类
最新评论

java核心技术总结八--多线程

    博客分类:
  • java
 
阅读更多

1、多线程程序在较低的层次上扩展了多任务的概念: 一个程序同时执行多个任务。通常,每一个任务称为一个线程,它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序。

2、 每个进程拥有自己的 一整套变量,而线程则共享数据。共享变量使线程之间的通信比进程之间的通信更有效,更容易。

3、sleep方法是Thread类的静态方法,用于暂停当前线程的活动,调用Thread.sleep()方法不会创建一个新线程。

4、并行运行多个任务的操作:

1)、将任务代码移到实现了Runnable接口的类的run方法中

2)、创建一个类对象

3)、由Runnable创建一个Thread对象

4)、启动线程

5、interrupt 、interrupted 和isInterrunpted的区别:

interrupt方法是向线程发送中断请求,线程的中断状态将被设置为true;

interrupted方法是一个静态方法,它检测当前的线程是否被中断,而且调用interrupted方法会清除该线程的中断状态.它将当前线程的中断状态重置为false;

isInterrupted方法是一个实例方法,可以用来检验是否有线程被中断,调用这个方法不会改变中断状态

6、线程状态:

new(新生)  用new thread()创建一个新线程

runnable(可运行) 一旦调用start()方法,线程就处于runnable状态

blocked(被阻塞)

waiting(等待)

Timed waiting(计时等待)

当线程处于被阻塞或者等待状态时,它暂时不活动,它不运行任何代码且消耗最少的资源,直到线程调度器重新激活它。

当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态;

当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。

有几个方法有一个超时参数,调用它们导致线程进入计时等待状态。这一状态将一直保持直到超时期满或者接受到适当的通知。带有超时参数的方法有:Thread.sleep,Object.wait,Thread.join,Lock.tryLock,Condition.await


Terminated(被终止)

线程被终止的原因:

1)、因为run方法正常退出而自然死亡

2)、因为一个没有捕获的异常终止了run方法而意外死亡

7、线程属性:

1)、线程优先级:优先级顺序是从1到10;

2)、守护线程: 其唯一的好处是为其他线程提供服务;

3)、线程组:

线程组类实现Thread.UncaughtExceptionHandler接口。它的uncaughtException方法做如下操作:

(1)、如果该线程组有父线程,则父线程组的uncaughtException方法被调用;

(2)、否则,如果Thread.getDefaultExceptionHandler方法返回一个非空的处理器,则调用该处理器;

(3)、否则,如果Throwable是ThreadDeath的一个实例,什么都不做;

(4)、否则,线程的名字以及Throwable的栈踪迹被输出到System.err上;

4)、处理未捕获异常的处理器

8、同步

8.1、锁对象:ReentrantLock类对象。

     每一个对象有自己的ReentrantLock对象,如果两个线程试图访问同一个对象,那么锁以串行的方式提供服务。

     锁是可重入的,因为线程可以重复的获得已经持有的锁。锁保持一个持有技术来跟踪 对lock方法的嵌套调用。线程在每一个调用lock都要调用unlock来释放锁。

8.2、条件对象:通常线程进入临界区,却发现在某一条件满足之后它才能执行,要使用一个条件对象来管理那些已经获得了一个锁但是却不能做有用工作的线程。条件对象经常被称为条件变量。

    一个锁对象可以有一个或多个相关的条件对象,可以用newCondition方法获得一个条件对象。当方法的条件不能满足时,当前线程被阻塞,并放弃了锁。等待获得锁的线程和调用await方法的线程存在本质上的区别。一旦一个线程调用await方法,它进入该条件的等待集。当锁可用时,该线程不能马上解除阻塞。相反,它处于阻塞状态,直到另一个线程调用同一个条件上的signalAll方法时为止。

   当一个线程调用await时,它没有办法重新激活自身。在对象的状态有利于等待线程的方向改变时调用signalAll。signalAll不会立即激活一个等待线程,它仅仅解除等待线程的阻塞。

  当一个线程拥有某个条件的锁时,它仅仅可以在该条件上调用await,signalAll 或signal方法。

9、锁和条件的关键之处:

1)、锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码

2)、锁可以管理试图进入被保护代码段的线程

3)、锁可以拥有一个或多个相关的条件对象

4)、每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程。

10、synchronized关键字

      如果一个方法用synchronized关键字声明,那么对象的锁将保护整个方法。这个锁也被称为内部对象锁,它只有一个相关条件。wait方法添加一个线程到等待集中,notify/notifyAll方法解除等待线程的阻塞状态。

   wait、notifyAll以及notify方法是Object类的final方法,它和Condition类的方法await、signalAll和signal功能类似。

   内部锁和条件存在一些局限性:

   1)、不能中断一个正在试图获得锁的线程;

   2)、试图获得锁时不能设定超时;

   3)、每个锁仅有单一的条件,可能是不够的。

11、 使用synchronized和 lock/condition的建议:

1、最好既不用用lock/condition也不要使用synchronized关键字。在许多情况下可以使用java.util.concurrent包中的一种机制,它会处理所有的加锁。

2、如果synchronized关键字适合你的程序,则尽量使用它,这样可以减少编写的代码数量,减少出错的几率。

3、如果特别需要lock/condition结构提供的独有特性时,才使用lock/condition.

12、同步阻塞

同步阻塞是另外一种获得锁的方式。

有时程序员使用一个对象的锁来实现额外的原子操作,实际上称为客户端锁定。客户端锁定是非常脆弱的,通常不推荐使用。

13、监视器

1、监视器具有的特性有:

    监视器是只包含私有域的类

    每个监视器类的对象有一个相关的锁

    使用该锁对所有的方法进行加锁

    该锁可以有任意多个相关条件

2、java对象不同于监视器的方面:

     域不要求必须是private

    方法不要求必须是synchronized

    内部锁对客户是可用的

14、同步格言:

如果向一个变量写入值,而这个变量接下来可能会被另外一个线程读取,或者,从一个变量读取,而这个变量可能是之前被另一个线程写入的,此时必须使用同步。

15、volatile

volatile关键字为实例域的同步访问提供了一种免锁机制,如果声明一个域为volatile,则编译器和虚拟机就知道该域是可能被另外一个线程并发更新的。

volatile变量不能提供原子性

16、域的并发访问是安全的条件:

    域是final,并且在构造器调用完成之后被访问

    对域的访问由公有的锁进行保护

    域是volatile的

17、锁测试和超时

tryLock方法试图申请一个锁,在成功获得锁后返回true。否则返回false。tryLock允许程序打破死锁。

18、读写锁

使用读/写锁的必要步骤:

构造一个ReentrantReadWriteLock对象;

抽取读锁和写锁;

对所有的访问者加读锁;

对所有的修改者加写锁;写者线程必须是互斥访问的。

19、stop和suspend方法被弃用的原因

    stop方法天生就不安全,该方法会终止所有未结束的方法,包括run方法。当线程被终止,立即释放它锁住的所有对象的锁。

suspend不会破坏对象,但是很容易造成死锁。但是如果用suspend挂起一个持有一个锁的线程,则该锁在恢复之前是不可用的。如果调用suspend方法的线程试图获得同一个锁,则程序死锁。被挂起的线程等着被恢复,而将其挂起的线程等待获得锁。

20、阻塞队列

阻塞队列的几个变种:

LinkedBlockingQueue: 容量没有上边界,但是可以选择指定最大容量。它是一个双端的版本。

ArrayBlockingQueue:在构造时需要指定容量,并且有一个可选的参数来指定是否需要公平性。

PriorityBlockingQueue: 它是一个带优先级的队列,而不是先进先出队列。元素按照它们的优先级顺序被移出。该队列的容量没有上界。

DelayQueue

阻塞队列的方法:

add         添加一个元素。                      如果队列满,则抛出异常

element  返回队列的头元素。                 如果队列空,抛出NoSuchElementException异常

offer        添加一个元素并返回true。       如果队列满,返回false

peek       返回队列的头元素。                 如果队列空,则返回null

poll         移出并返回队列的头元素。        如果队列空,则返回null

put         添加一个元素。                       如果队列满,则阻塞

remove   移出并返回头元素。                如果队列空,则抛出异常

take        移出并返回头元素。                如果队列空,则阻塞


poll和peek方法返回空来指示失败,因此向这些队列中插入null值是非法的。

21、线程安全的集合

java.util.concurrent包提供了映像、有序集和队列的高效实现: ConcurrentHashMap、ConcurrentSkipListMap、

ConcurrentLinkedQueue 。这些集合使用复杂的算法,通过允许并发的访问数据结构不同的部分来使竞争极小化。集合返回弱一致性的迭代器。

并发的散列映像表,可高效的支持大量的读者和一定数量的写者。默认情况下,假定可以有多达16个写者线程同时执行。

ConcurrentHashMap和ConcurrentSkipListMap类有相应的方法用于原子性的关联插入以及关联删除。putIfAbsent方法自动地添加新的关联,前提是原来没有这一关联。

22、写数据的拷贝

CopyOnWriteArrayList和CopyOnWriteArraySet是线程安全的集合,其中所有的修改线程对底层数组进行复制。

23、旧的线程安全的集合

Vector和Hashtable类提供了线程安全的动态数组和散列表的实现。在java1.2中,这些类被弃用了,取而代之的是ArrayList和HashMap类。这些类不是线程安全的,而集合库中提供了不同的机制。任何集合类通过使用同步包装器变成线程安全的。

24、执行器

使用线程池的理由:

1、构建一个新的线程是有一定代价的,因为涉及与操作系统的交互。如果程序中创建了大量的生命期很短的线程,应该使用线程池。一个线程池中包含许多准备运行的空闲线程。当Runnable对象交给线程池,就会有一个线程调用run方法。当run方法退出时,线程不会死亡,而是在池中准备为下一个请求提供服务。

2、减少并发线程的数目

25、执行者工厂方法

方法                                             描述

newCachedThreadPool       必要时创建新线程,空闲线程会被保留60秒

newFixedThreadPool   该池包含固定数量的线程,空闲线程会一直被保留

newSingleThreadExecutor  只有一个线程的"池",该线程顺序执行每一个提交的任务

newScheduledThreadPool   用于预定执行而构建的固定线程池,替代java.util.Timer

newSingleThreadScheduledExecutor   用于预定执行而构建的单线程"池"

26、在使用线程池时应该做的事情:

1)、调用Executors类中静态的方法newCachedThreadPool或newFixedThreadPool

2)、调用submit提交Runnable或callable对象

3)、如果想要取消一个任务,或如果提交Callable对象,那就要保存好返回的Future对象

4)、当不再提交任何任务时,调用shutdown。

27、同步器

1)、fly信号量

2)、倒计时门栓

3)、障栅

4)、交换器。当两个线程在同一个数据缓冲区的两个实例上工作的时候,就可以使用交换器。典型的情况是:一个线程向缓冲区填入数据,另一个线程消耗这些数据。当它们都完成以后,相互交换缓冲区。

5)、同步队列。它是一种将生产者与消费者线程配对的机制。当一个线程调用SynchronousQueue的put方法时,它会阻塞直到另一个线程调用take方法为止。






分享到:
评论

相关推荐

    Java多线程核心技术讲解

    Java多线程核心技术:理解多线程、在Java中实现多线程、线程的生命周期、线程的优先级、线程的同步、线程的阻塞、守护线程、线程组、线程池、总结。

    java多线程核心技术

    结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如服务器、数据库、应用。多线程可以有效提升计算和处理效率,大大提升吞吐量和可伸缩性,...

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    Java 高并发编程相关知识, 接下来将阅读该书, 并且进行比较详细的总结, 好记性不如烂笔头, 加油。 Java 多线程编程实战指南。

    java多线程技术整理

    看完了java多线程编程核心技术一书,总结

    多线程核心

    Java多线程编程核心技术是资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著。本书以浅白的措辞,结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的...

    Java多线程编程核心+带目录版

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著  

    java concurrent source code

    结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 封底 Java多线程无处不在,如服务器、数据库、应用。多线程可以有效提升计算和处理效率,大大提升吞吐量和可...

    《Java2核心技术》笔记

    《Java2核心技术》笔记 作者:叶加飞 加拿大.达内科技 (上海中心) 笔记包含以下文档: 面向对象技术总结.pdf corejava高级个性总结.pdf 接口学习总结.pdf 异常和内部类.pdf 集合框架学习总结.pdf GUI和AWT事件模型....

    Java课堂笔记、代码、java核心知识点梳理、java笔试面试资料.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    Java面试知识总结.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    全网最齐全的Java面试题库-附答案-持续更新.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    Java面试总结.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    Java interview-高级Java面试题2023.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    Java后台工程师面试总结.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    【Java面试+Java学习指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    一份超级详细的Java面试题【大厂面试真题+Java学习指南+工作总结】.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    中华石杉--互联网Java进阶面试训练营.zip

    Java核心技术:如多线程、网络编程、序列化等都有详细的解释和示例。 常用框架:如Spring、MyBatis等框架的使用方法和内部原理都有涉及。 数据库相关:包括关系型数据库和非关系型数据库的使用,以及JDBC、MyBatis等...

    java8源码-JavaSE-Code:JavaSE的代码练习与学习笔记总结

    [Java多线程核心编程技术] 书籍笔记 第一章:Java多线程技能 线程是进程中的子任务 interrupted与isInterrupted的区别: interrupted是Thread类的静态方法,里面调用了isTnterrupted方法[currentThread().isInterrupted...

Global site tag (gtag.js) - Google Analytics