`
hesihua
  • 浏览: 233751 次
  • 性别: 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核心技术总结.pdf

    Java核心技术总结 Java是一种面向对象的编程语言,它的核心技术包括Java虚拟机(JVM)、Java核心技术、Java并发编程、计算机网络等。以下是Java核心技术的总结: 一、Java虚拟机(JVM) Java虚拟机(JVM)是Java ...

    java 技术总结.--java 技术

    这篇“Java技术总结”将深入探讨Java的核心概念、语法特性、开发工具以及相关框架,旨在为学习者提供一个全面且深入的Java知识体系。 一、Java语言基础 Java是一种面向对象的编程语言,由Sun Microsystems(现已被...

    Java多线程核心技术讲解

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

    JAVA多线程编程技术PDF

    总结起来,“JAVA多线程编程技术PDF”涵盖了多线程的基本概念、同步机制、线程通信、死锁避免、线程池以及线程安全的集合类等内容。通过深入学习这份资料,开发者可以全面掌握Java多线程编程技术,提升程序的并发...

    Java核心技术介绍-java核心技术讲解word格式可编辑.docx

    ### Java核心技术介绍 #### 一、Java网络编程基础 Java的核心技术之一是其强大的网络编程支持,这得益于Java建立在TCP/IP网络平台上的特性。Java的库函数提供了使用HTTP和FTP协议来发送和接收信息的方法,这对于...

    Java核心技术+卷1+基础知识+原书第10版-中文版扫描-带书签已OCR

    #### 八、多线程编程 - **线程概念**:介绍进程与线程的区别、线程生命周期等基本概念。 - **线程创建与同步**:如何创建线程、实现线程同步避免数据竞争问题。 - **并发工具类**:如CountDownLatch、Semaphore等...

    java多线程学习-ftp上传

    Java多线程学习是编程领域中的重要一环,特别是在服务器端和网络编程中,多线程技术能够有效地利用系统资源,提高程序的并发性。FTP(File Transfer Protocol)上传则是通过网络将本地文件传输到远程服务器的过程。...

    基于tesseract的多线程OCR服务器的JAVA实现

    总结起来,这个项目提供了一个高效、可靠的OCR服务解决方案,利用Java的多线程特性以及Tesseract的强大识别能力,实现了对图像文本的快速处理。这不仅简化了开发者的集成工作,也为用户提供了便捷的服务,适用于各种...

    java多线程核心编程技术

    ### Java多线程核心编程技术 #### 一、Java多线程基础 ##### 1.1 线程的概念 在计算机科学中,线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。在Java中,通过创建`...

    java多线程分页查询

    通过对上述代码的分析可以看出,该方案充分利用了Java多线程技术的优势,通过预加载前一页的数据,大大提高了后续请求的响应速度。然而,在实际应用中还需要注意以下几点: - **线程池管理**:频繁地创建新线程可能...

    Java多线程英文版

    本文将详细介绍Java多线程编程的核心概念和技术要点,并通过与POSIX线程(Pthreads)以及其他平台线程模型的对比,帮助读者更好地理解和应用Java多线程。 #### 二、多线程范式 多线程编程是指在一个程序中并发执行...

    Java核心技术 第八版 卷Ⅰ(基础篇)电子版

    ### Java核心技术 第八版 卷Ⅰ:基础知识 #### 一、概述 《Java核心技术》第八版卷Ⅰ,作为Sun公司核心技术丛书中的一部重要著作,由Cay S. Horstmann和Gary Cornell共同撰写,是Java学习者和开发者不可多得的经典...

    JAVA核心面试知识整理-最全

    以下是一份全面的Java核心面试知识点总结: 一、基础语法 1. 变量与数据类型:Java支持八种基本数据类型,包括整型、浮点型、字符型和布尔型。变量必须先声明后使用,遵循驼峰命名规则。 2. 类与对象:Java是一种...

    2020最新Java企业面试题汇总-1000多份.txt

    ### 二、Java核心技术 #### 1. 异常处理 - **异常分类**:编译时异常(检查异常)和运行时异常(非检查异常)。 - **异常处理机制**:try-catch-finally、throws声明、自定义异常。 #### 2. 集合框架 - **集合接口**:...

    40个Java多线程问题总结

    ### Java多线程问题总结 #### 一、多线程的作用与优势 1. **发挥多核CPU的优势:** - 当今计算机硬件普遍配备有多核CPU,利用多线程技术能够有效地分配任务到不同的核心上,使得计算资源得到最大化利用。在双核...

    中信java培训资料------第一部分

    这份资料旨在帮助初学者建立起坚实的Java编程基础,并逐步熟悉其核心概念和技术。 在【听课笔记(6月22日).doc】中,可能详细记录了当天课程的主要内容,包括Java的起源、发展历程、基本语法结构,如变量声明、数据...

    JAVA多线程(精典总结)

    本文将深入探讨Java多线程的核心概念、创建方式、线程状态转换、线程调度以及线程优先级调整。 首先,理解线程的基本概念至关重要。线程是进程中的一个执行单元,是操作系统调度的基本单位。与进程相比,线程更轻...

    《深入理解Java 7 核心技术与最佳实践》PDF版本下载.txt

    - **多线程编程**:详细介绍了Java中的多线程编程技术,包括线程的创建、同步、通信等关键概念。 - **网络编程**:讲解了Java网络编程的相关知识,包括Socket编程和HTTP编程等内容。 #### 3. **高级特性** - **...

Global site tag (gtag.js) - Google Analytics