您好,登录后才能下订单哦!
这篇文章主要介绍“Java并发编程怎么理解”,在日常操作中,相信很多人在Java并发编程怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java并发编程怎么理解”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁)。
happens-before简介
从JDK 5开始,Java使用新的JSR-133内存模型(除非特别说明,本文针对的都是JSR-133内存模型)。JSR-133使用happens-before的概念来阐述操作之间的内存可见性。在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间
·程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
·监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
·volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
·传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
注意 两个操作之间具有happens-before关系,并不意味着前一个操作必须要在后一个操作之前执行!happens-before仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前(the first is visible to and ordered before the second)。
3.2 重排序
重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
3.2.1 数据依赖性
如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间
就存在数据依赖性
as-if-serial语义
as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)
程序的执行结果不能被改变
顺序一致性内存模型
其实就是线程所见都是单一的执行顺序,i++就是编译指令为4步的非原子操作,执行顺序可变
数据通过总线在处理器和内存之间传递。每次处理器和内存之间的数据传递都是通过一系列步骤来完成的,这一系列步骤称之为总线事务(Bus Transaction)。
疑问?这个总线与CPU的总线是一个概念吗?宏观的作用上差不多
如图 来自B站柏義
volatile禁止指令重排是因为LoadStore导致的不能重排
对公平锁和非公平锁的内存语义做个总结。
·公平锁和非公平锁释放时,最后都要写一个volatile变量state。
·公平锁获取时,首先会去读volatile变量。
·非公平锁获取时,首先会用CAS更新volatile变量,这个操作同时具有volatile读和volatile写的内存语义。
线程的优先级
Deamon线程(美[ˈdiːmən])
Daemon线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。这意味着,当一个Java虚拟机中不存在非Daemon线程的时候,Java虚拟机将会退出。可以通过调用Thread.setDaemon(true)将线程设置为Daemon线程。
1.当主线程退出时,守候子线程会执行完毕吗?
不一定执行
ti.setDaemon(true);
守候线程执行依赖于执行时间
理解中断
Thread.interrupt() 设置状态
isInterrupted() 判断 返回Boolean
interrupted 即判断又清除
中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线程进行了中断操作。中断好比其他线程对该线程打了个招呼,其他线程通过调用该线程的interrupt()方法对其进行中断操作。
线程通过检查自身是否被中断来进行响应,线程通过方法isInterrupted()来进行判断是否被中断,也可以调用静态方法Thread.interrupted()对当前线程的中断标识位进行复位.
线程池技术及其实例
ThreadPoolExecutor源码
// 执行一个Job,这个Job需要实现Runnablepublic void execute(Runnable command) {} // 关闭线程池public void shutdown() {}处理正在等待的任务,并返回任务列表public List<Runnable> shutdownNow() {}//1)菜用循环CAS操作来将线程数加1;2)新建一个线程并启用。private boolean addWorker(Runnable firstTask, boolean core) {}//获取线程池数量public int getPoolSize() {}
到此,关于“Java并发编程怎么理解”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。