内容简介:这个方式基本不用,会影响线程的思想。有一个核心线程常驻。可以保证执行顺序。FIFOmonitorenter :Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref,
1.基本并发方式
1.1 Callable
这个方式基本不用,会影响线程的思想。
2.线程池 Executor
2.1 ThreadExecutor
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
- corePoolSize 线程池Idle状态的线程。
- maximumPoolSize 线程池支持的最大线程数,这个数达到某个值以后,就会导致OOM,可以理解如果有100多个线程,会不会导致内存不足以分配这么多线程。
- defaultHandler 这个就是丢弃策略。这个不是线程等待的时候丢弃,是线程池里面有超过maximumPoolSize的时候丢弃。
2.2 CachedThreadPool
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
这个作用是什么,就是没有核心线程,有新的runnable进来,就new 一个线程执行。如果空闲线程在60s内,还没有被回收,就达到复用的目的。所以线程是存在复用的可能,但是不会等待。
2.3 FixedThreadPool
ExecutorService executorService = Executors.newFixedThreadPool(2);
这个才是最常用的线程池方式。
线程调度,在池满以后等待。
2.4 SingleFixedThreadPool
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
有一个核心线程常驻。可以保证执行顺序。FIFO
sleep,interrupt,yield,join,notify,wait,await
3. 同步
3.1synchronized
- 作用在局部区域上
- this
- class.name
- 作用的实例方法上
- 作用在静态方法上
这4种使用方式作用的区域各不相同。3.1.1 synchronized this
这个锁住的是this,也就是当前实例。
比如有2个方法,一个read,一个write,这个就是要加锁来解决的。
如果是2个实例,他们相互直接的synchronized是不相干的。
3.1.2 synchronized static or class.name
static synchronized 的作用域是所有的静态方法。
这个3.1.1 和3.1.2的synchronized 的作用范围不同,所以没有相关性。
static方法的使用,本质上跟class类是没有关系的,只有一个索引用以找到这个方法。所以它sync的不是所有实例对象,sync的就是这个class.name。
3.2 Synchronizd 的本质
-
synchronized this 本质是在执行的过程中,加上了锁。
锁是由JVM自动取解析的。
$ javap -c SynchronizedDemo 警告: 二进制文件SynchronizedDemo包含com.demanmath.androidms.javabase.concurrent.SynchronizedDemo Compiled from "SynchronizedDemo.java" public class com.demanmath.androidms.javabase.concurrent.SynchronizedDemo { public com.demanmath.androidms.javabase.concurrent.SynchronizedDemo(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public void testA(); Code: 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: iconst_0 5: istore_2 6: aload_1 7: monitorexit 8: goto 16 11: astore_3 12: aload_1 13: monitorexit 14: aload_3 15: athrow 16: return Exception table: from to target type 4 8 11 any 11 14 11 any public static synchronized void testB(); Code: 0: iconst_0 1: istore_0 2: return }
monitorenter,monitorexit 这2条指令,就是JVM控制同步的方式。
关于这两条指令的作用,我们直接参考 JVM 规范中描述:
monitorenter :Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:
• If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
• If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.
• If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.
这段话的大概意思为:每个对象有一个监视器锁(Monitor),当 Monitor 被占用时就会处于锁定状态。
线程执行 Monitorenter 指令时尝试获取 Monitor 的所有权,过程如下:
如果 Monitor 的进入数为 0,则该线程进入 Monitor,然后将进入数设置为 1,该线程即为 Monitor 的所有者。
如果线程已经占有该 Monitor,只是重新进入,则进入 Monitor 的进入数加 1。
如果其他线程已经占用了 Monitor,则该线程进入阻塞状态,直到 Monitor 的进入数为 0,再重新尝试获取 Monitor 的所有权。
monitorexit:The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.
The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner.
Other threads that are blocking to enter the monitor are allowed to attempt to do so.
这段话的大概意思为:执行 Monitorexit 的线程必须是 Objectref 所对应的 Monitor 的所有者。
指令执行时,Monitor 的进入数减 1,如果减 1 后进入数为 0,那线程退出 Monitor,不再是这个 Monitor 的所有者。
其他被这个 Monitor 阻塞的线程可以尝试去获取这个 Monitor 的所有权。
通过这两段描述,我们应该能很清楚的看出 Synchronized 的实现原理。
-
在反编译方法以后,会看到方法带有ACC_SYNCHRONIZED 标志位。
所以方法在运行的时候,获取当前方法的实例对象,进行monitor,锁住。
因此整个synchronized 作用方式就2种,对象和方法。当然静态时候 是另外2个case,所以一共4个case。
以上所述就是小编给大家介绍的《Java并发》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Java并发系列—并发编程基础
- [Java并发-17-并发设计模式] Immutability模式:如何利用不变性解决并发问题?
- JAVA并发编程之并发模拟工具
- Java并发系列—并发编程的挑战
- Core Java 并发:理解并发概念
- [Java并发-11] 并发容器的使用
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
MySQL技术内幕
姜承尧 / 机械工业出版社 / 2013-5 / 79.00元
《MySQL技术内幕:InnoDB存储引擎(第2版)》由国内资深MySQL专家亲自执笔,国内外多位数据库专家联袂推荐。作为国内唯一一本关于InnoDB的专著,《MySQL技术内幕:InnoDB存储引擎(第2版)》的第1版广受好评,第2版不仅针对最新的MySQL 5.6对相关内容进行了全面的补充,还根据广大读者的反馈意见对第1版中存在的不足进行了完善,《MySQL技术内幕:InnoDB存储引擎(第2......一起来看看 《MySQL技术内幕》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
正则表达式在线测试
正则表达式在线测试