关闭

Java并发必须知道的零碎知识(二)

340人阅读 评论(0) 收藏 举报
分类:

1.  Wait/notify与Condition.await /condition.signal /Condition.signalAll

一个Condition和一个Lock关联在一起,就想一个条件队列和一个内置锁相关联一样。要创建一个Condition,可以在相关联的Lock上调用Lock.newCondition方法。正如Lock比内置加锁提供了更为丰富的功能,Condition同样比内置条件队列提供了更丰富的功能:在每个锁上可存在多个等待、条件等待可以是可中断的或者不可中断的、基于时限的等待,以及公平的或非公平的队列操作。与内置条件队列不同的是,对于每个Lock,可以有任意数量的Condition对象。Condition对象继承了相关的Lock对象的公平性,对于公平的锁,线程会依照FIFO顺序从Condition.await中释放。

注意:在Condition对象中,与wait,notify和notifyAll方法对于的分别是await,signal,signalAll。但是,Condition对Object进行了扩展,因而它也包含wait和notify方法。一定要确保使用的版本——await和signal.

Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。


2.  如何避免死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:

 

    互斥条件:一个资源每次只能被一个进程使用。

    请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

    不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

    循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

 

避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。


3.  有三个线程T1,T2,T3,怎么确保它们按顺序执行

在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。

 

如果一个线程A执行了thread.join()语句,其含义是:当前线程A等待thread线程终止之后才从thread.join()返回。join与synchronized的区别是:join在内部使用wait()方法进行等待,而synchronized关键字使用的是“对象监视器”做为同步。

join提供了另外两种实现方法:join(long millis)和join(long millis, int nanos),至多等待多长时间而退出等待(释放锁),退出等待之后还可以继续运行。内部是通过wait方法来实现的。


4.  如果你提交任务时,线程池队列已满。会时发会生什么

这个问题问得很狡猾,许多程序员会认为该任务会阻塞直到线程池队列有空位。事实上如果一个任务不能被调度执行那么ThreadPoolExecutor’s submit()方法将会抛出一个RejectedExecutionException异常。


5.  Java线程池中submit() 和 execute()方法有什么区别

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中,而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。


6.  如何在Java中创建Immutable对象?

这个问题看起来和多线程没什么关系, 但不变性有助于简化已经很复杂的并发程序。Immutable对象可以在没有同步的情况下共享,降低了对该对象进行并发访问时的同步化开销。可是Java没有@Immutable这个注解符,要创建不可变类,要实现下面几个步骤:通过构造方法初始化所有成员、对变量不要提供setter方法、将所有的成员声明为私有的,这样就不允许直接访问这些成员、在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝。


7.  yield方法

yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但放弃时间不确定,有可能刚刚放弃,马上又获得CPU时间片。这里需要注意的是yield()方法和sleep方法一样,线程并不会让出锁,和wait不同。


8.  守护线程

Java中有两种线程,一种是用户线程,另一种是守护线程。当进程中不存在非守护线程了,则守护线程自动销毁。通过setDaemon(true)设置线程为后台线程。注意thread.setDaemon(true)必须在thread. Start()之前设置,否则会报IllegalThreadStateException异常;在Daemon线程中产生的新线程也是Daemon的;在使用ExecutorSerice等多线程框架时,会把守护线程转换为用户线程,并且也会把优先级设置为Thread.NORM_PRIORITY。在构建Daemon线程时,不能依靠finally块中的内容来确保执行关闭或清理资源的逻辑。


9.  线程安全的非阻塞队列

非阻塞队列有ConcurrentLinkedQueue, ConcurrentLinkedDeque。元素不能为null。以ConcurrentLinkedQueue为例,有头head和尾tail两个指针,遵循FIFO的原则进行入队和出队,方法有add(E e), peek()取出不删除, poll()取出删除, remove(Object o),size(), contains(Objecto), addAll(Collection c), isEmpty()。ConcurrentLinkedDeque是双向队列,可以在头和尾两个方向进行相应的操作。


10. 阻塞队列

ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。

LinkedeBlockingQueue:一个有链表结构组成的有界阻塞队列。

PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列

DelayQueue:一个使用优先级队列实现的无界阻塞队列。

SynchronousQueue:一个不存储元素的阻塞队列。

LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。

LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

见连接:http://www.cnblogs.com/dolphin0520/p/3932906.html


11. Happens-Before规则

程序顺序规则:如果程序中操作A在操作B之前,那么在线程中A操作将在B操作之前。

监视器锁规则:一个unlock操作现行发生于后面对同一个锁的lock操作。

volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的“后面”同样是指时间上的先后顺序。

线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作。

线程终止规则:线程的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值等于段检测到线程已经终止执行。

线程中断规则:线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生。

终结器规则:对象的构造函数必须在启动该对象的终结器之前执行完成。

传递性:如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。

 

12. 如何避免死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,他们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足一下4个条件:

互斥条件:一个资源每次只能被一个进程使用。

请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序做操作来避免死锁。


1.  多线程之间如何进行信息交互

 

2.  如何停止一个线程

 

3.  什么是线程安全、如何保证

 

4.  Sleep和wait的区别



0
0
查看评论

Java并发必须知道的零碎知识(一)

1.  线程和进程 进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能。 但是要注意,一个进程虽然包括多个线程,但是这些线程是共同享有进程占有的资源和地址空间的。进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位。   2.  实现线程...
  • luotuomianyang
  • luotuomianyang
  • 2016-08-29 22:01
  • 471

vue 零碎知识点

一、Vue获取url链接的参数 this.$route.query.参数名 二、Vue标签绑定两个事件中间用;隔开
  • hyupeng1006
  • hyupeng1006
  • 2017-12-14 15:41
  • 64

java中必须要掌握的知识

什么是面向对象 *                 是一种更符合我们思想的习惯的懒人思想 *                 可以将复杂...
  • guwoei
  • guwoei
  • 2016-06-30 18:54
  • 1048

Java程序员必须掌握的知识

1、首先要对java语法和语义有相当的理解及纯熟的应用,比方说对继承体系中的对象的比较复杂初始化顺序的清晰把握,对内部类和匿名内部类的理解和使用时机的把握,对反射和序列化机制的掌握,等等; 2、规范:编写的代码必须符合流行的编码规范,例如类名首字母大写,成员和方法名首字母小写,方法名的第一个单词一...
  • guangzhaolove
  • guangzhaolove
  • 2013-12-30 16:24
  • 1040

【php-零碎知识】defined & define & const & isset & function_exist()

define:定义一个常量defined:确定一个常量是否存在,存在返回true,否则返回false一般用法:$env = get_cfg_var('env'); defined('YII_ENV') or define('YII_ENV', $en...
  • csdn_azuo
  • csdn_azuo
  • 2018-01-18 21:24
  • 16

关于并发的零碎知识

一、线程本地存储(ThreadLocal) 防止任务在共享资源上产生冲突的方式就是避免使用同步。即根除对变量的共享。线程本地存储是一种自动化机制,可以为使用相同变量的每个不同的线程都创建不同的存储。因此,如果你有5个线程都要使用变量x所表示的对象,那线程本地存储就会生成5个用于x的不同存储块。主要是...
  • yangnan0110
  • yangnan0110
  • 2015-04-15 22:58
  • 176

Java并发与多线程教程(2)

Java同步块 Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java同步块用来避免竞争。本文介绍以下内容: Java同步关键字(synchronzied)实例方法同步静态方法同步实例方法中同步块静态方法中同步块Java同步示例 ...
  • zhoudaxia
  • zhoudaxia
  • 2014-05-15 14:47
  • 3654

Java并发你必须知道的结构

1.  ConcurrentHashMap     ConcurrentHashMap是线程安全的HashMap,内部采用分段锁来实现,默认初始容量为16,装载因子为0.75f,分段16,每个段的HashEntry[]大小为2。键值都不能为null。每次扩容为...
  • luotuomianyang
  • luotuomianyang
  • 2016-08-29 21:56
  • 489

Java中的并发知识点梳理

记录java多线程的学习过程
  • qq_34250022
  • qq_34250022
  • 2017-06-08 16:04
  • 83

Web开发应该知道的计算机网络知识

前言 作为一名程序员, 不可能不与网络打交道. 现在我们的手机, 电脑, 不夸张地说, 离开了网络就是一块’废铁’, 它们的作用将大打折扣.. 本文的作用呢,主要是针对不是非网络专业开发的人员准备的, 以’最短的时间, 了解计网最多的知识’为前提起笔. 概述 先来了解下各种我们...
  • tTU1EvLDeLFq5btqiK
  • tTU1EvLDeLFq5btqiK
  • 2017-11-22 00:00
  • 147
    个人资料
    • 访问:52081次
    • 积分:1530
    • 等级:
    • 排名:千里之外
    • 原创:97篇
    • 转载:41篇
    • 译文:0篇
    • 评论:24条
    最新评论