并发编程系列
JordanInShenzhen
这个作者很懒,什么都没留下…
展开
-
java并发编程(二)-- 线程中断
使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。 下面一段代码演示了休眠线程的中断:public class S转载 2016-06-12 00:32:30 · 545 阅读 · 0 评论 -
java并发编程(十五)--线程间通信中notifyAll造成的早期通知问题
如果线程在等待时接到通知,但线程等待的条件还不满足,此时,线程接到的就是早期通知,如果条件满足的时间很短,但很快又改变了,而变得不再满足,这时也将发生早期通知。这种现象听起来很奇怪,下面通过一个示例程序来说明问题。 很简单,两个线程等待删除List中的元素,同时另外一个线程正要向其中添加项目。代码如下:import java.util.*;public class Ear转载 2016-06-13 12:35:30 · 474 阅读 · 0 评论 -
java并发编程(十六)--生产者—消费者模型
生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。 这里实现如下情况的生产--消费模型: 生产者不断交替地生产两组数据“姓名--1 --> 内容--1”,“姓名--2--> 内容--2”,消费者不断交替地取得这两组数据,这里的“姓名--1”和“姓名--2”模拟为数据的名称,“内容--1 ”转载 2016-06-13 12:42:03 · 519 阅读 · 0 评论 -
java并发编程(十八)--深入Java内存模型—内存操作规则总结
主内存与工作内存 Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量主要是指共享变量,存在竞争问题的变量。Java内存模型规定所有的变量都存储在主内存中,而每条线程还有自己的工作内存,线程的工作内存中保存了该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不转载 2016-06-13 12:49:57 · 712 阅读 · 0 评论 -
java并发编程(十九)--并发新特性—Executor框架与线程池
Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了转载 2016-06-13 12:58:52 · 700 阅读 · 0 评论 -
java并发编程(二十)--并发新特性—Lock锁和条件变量
简单使用Lock锁 Java 5中引入了新的锁机制——java.util.concurrent.locks中的显式的互斥锁:Lock接口,它提供了比synchronized更加广泛的锁定操作。Lock接口有3个实现它的类:ReentrantLock、ReetrantReadWriteLock.ReadLock和ReetrantReadWriteLock.WriteLock,即重入锁、转载 2016-06-13 13:04:02 · 1900 阅读 · 0 评论 -
java并发编程(二十一)--并发新特性—阻塞队列和阻塞栈
阻塞队列 阻塞队列是Java 5并发新特性中的内容,阻塞队列的接口是java.util.concurrent.BlockingQueue,它有多个实现类:ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等,用法大同小异,具体可查看JDK文档,这里简单举例看下转载 2016-06-13 13:15:21 · 538 阅读 · 0 评论 -
java并发编程(二十二)--并发新特性—障碍器CyclicBarrier
CyclicBarrier(又叫障碍器)同样是Java 5中加入的新特性,使用时需要导入java.util.concurrent.CylicBarrier。它适用于这样一种情况:你希望创建一组任务,它们并发地执行工作,另外的一个任务在这一组任务并发执行结束前一直阻塞等待,直到该组任务全部执行结束,这个任务才得以执行。这非常像CountDownLatch,只是CountDownLatch是只触发一次转载 2016-06-13 13:17:52 · 521 阅读 · 0 评论 -
java并发编程(二十三)--并发新特性—信号量Semaphore
在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步。当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定义实现类似Java中的synchronized、wait、notify机制。 Java并发包中的信号量Semaphore实际上是一个功能完毕的计数信号量,从概念上讲,它维护了一个许可集合转载 2016-06-13 13:19:33 · 505 阅读 · 0 评论 -
java并发编程-- 并发编程大合集
为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容按照由浅入深的学习顺序总结如下,点击相应的标题即可跳转到对应的文章 【Java并发编程】实现多线程的两种方法 【Java并发编程】线程的中断 【Java并发编程】正确挂起、恢复、终止线程 【Java并发编程】守护线程和线程阻塞 【Java并发编程】Vol转载 2016-06-11 17:18:19 · 1396 阅读 · 0 评论 -
java并发编程(十四)--线程间通信中notify通知的遗漏
notify通知的遗漏很容易理解,即threadA还没开始wait的时候,threadB已经notify了,这样,threadB通知是没有任何响应的,当threadB退出synchronized代码块后,threadA再开始wait,便会一直阻塞等待,直到被别的线程打断。 遗漏通知的代码 下面给出一段代码演示通知是如何遗漏的,如下:public class M转载 2016-06-13 12:31:47 · 550 阅读 · 0 评论 -
java并发编程(十三)--线程间协作:wait、notify、notifyAll
在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信。在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调用notify()方法或notifyAll()方法),在线程中调用notify()方法或notifyAll()方法,将通知其他线程从wait()方法处返回。 Object转载 2016-06-13 12:22:23 · 492 阅读 · 0 评论 -
java并发编程(十二)--可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁。线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。 当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会阻塞。然而,由于内置锁是可重入的,因此如果摸个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。“重入”意味转载 2016-06-13 12:18:42 · 487 阅读 · 0 评论 -
java并发编程(三)--线程挂起、恢复与终止的正确方法
挂起和恢复线程 Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会发生死锁条件——其他线程在等待该线程释放锁,但该线程却被挂起了,便会发生死锁。另外,在长时间计算期间挂起线程也可能导致问题。 下面的代码演示了通过休眠来延缓运行,模转载 2016-06-12 00:48:33 · 1678 阅读 · 0 评论 -
java并发编程(一)--Runnable和Thread实现多线程的区别
Java中实现多线程有两种方法:继承Thread类、实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下优势: 1、可以避免由于Java的单继承特性而带来的局限; 2、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的; 3、适合多个相同程序代码的线程转载 2016-06-11 18:21:31 · 717 阅读 · 0 评论 -
java并发编程(四)--守护线程与线程阻塞的四种情况
守护线程 Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程。 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通、非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程。当VM检测仅剩一个守护线程,而用户线程都已经退出运行转载 2016-06-12 22:03:36 · 481 阅读 · 0 评论 -
java并发编程(五)--volatile变量修饰符—意料之外的问题
volatile用处说明 在JDK1.2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,转载 2016-06-13 11:15:31 · 1170 阅读 · 0 评论 -
java并发编程(六)--volatile意外问题的正确分析解答
在上一篇博文中遗留了一个问题,就是volatile只修饰了missedIt变量,而没修饰value变量,但是在线程读取value的值的时候,也读到的是最新的数据。但是在网上查了很多资料都无果,看来很多人对volatile的规则并不是太清晰,或者说只停留在很表面的层次,一知半解。 这两天看《深入Java虚拟机——JVM高级特性与最佳实践》第12章:Java内存模型与线程,并在网上查阅了转载 2016-06-13 11:29:32 · 630 阅读 · 0 评论 -
java并发编程(七)--使用synchronized获取互斥锁的几点说明
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确保在某一时刻,方法内只允许有一个线程。 采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个monitor(锁标记),当线程拥有这转载 2016-06-13 11:35:42 · 475 阅读 · 0 评论 -
java并发编程(八)--synchronized的另个一重要作用:内存可见性
加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性。我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化。而线程的同步恰恰也能够实现这一点。 内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。为了确保所有的线程都能看到共享变量转载 2016-06-13 11:45:55 · 472 阅读 · 0 评论 -
java并发编程(九)--并发编程中实现内存可见的两种方法比较:加锁和volatile变量
在上一篇博文中,讲述了通过同步实现内存可见性的方法,在http://blog.csdn.net/jordaninshenzhen/article/details/51655013这篇博文中,讲述了通过volatile变量实现内存可见性的方法,这里比较下二者的区别。 1、volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线转载 2016-06-13 11:58:08 · 550 阅读 · 0 评论 -
java并发编程(十)--多线程环境中安全使用集合API
在集合API中,最初设计的Vector和Hashtable是多线程安全的。例如:对于Vector来说,用来添加和删除元素的方法是同步的。如果只有一个线程与Vector的实例交互,那么,要求获取和释放对象锁便是一种浪费,另外在不必要的时候如果滥用同步化,也有可能会带来死锁。因此,对于更改集合内容的方法,没有一个是同步化的。集合本质上是非多线程安全的,当多个线程与集合交互时,为了使它多线程安全,必须采转载 2016-06-13 12:07:09 · 570 阅读 · 0 评论 -
java并发编程(十一)--死锁
当线程需要同时持有多个锁时,有可能产生死锁。考虑如下情形: 线程A当前持有互斥所锁lock1,线程B当前持有互斥锁lock2。接下来,当线程A仍然持有lock1时,它试图获取lock2,因为线程B正持有lock2,因此线程A会阻塞等待线程B对lock2的释放。如果此时线程B在持有lock2的时候,也在试图获取lock1,因为线程A正持有lock1,因此线程B会阻塞等待A对lock转载 2016-06-13 12:10:38 · 457 阅读 · 0 评论 -
java并发编程(二十四)--面试题合集
下面是Java线程相关的热门面试题,你可以用它来好好准备面试。1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。J2) 线程和进程有什么区别? 线程是进程转载 2016-06-13 16:08:48 · 1839 阅读 · 0 评论