java多线程并发编程(Java多线程与并发)
java多线程并发编程(Java多线程与并发)监视器对象是 当前对象实例synchronized 实例对象方法这里一定要理解清楚,我们 加锁的是监视器对象 ,而不是代码codesynchronized 静态方法监视器对象是所在Java类对应的 Class
1. volatitle
volatitle
对共享变量进行同步。在写入 volatitle
变量值之后,CPU缓存中的内容会被协会主存,再读取 volatitle
变量值时,缓存值为失效状态,然后重新从主存读取已改变过的值。
2. synchronized 关键字
所有的Java对象都有一个与之关联的监视器对象,允许在该监视器上进行加锁和解锁
这里一定要理解清楚,我们 加锁的是监视器对象 ,而不是代码code
-
synchronized
静态方法监视器对象是所在Java类对应的
Class
-
synchronized
实例对象方法监视器对象是
当前对象实例
-
synchronized
代码块代码块声明中的对象
2.1 synchronized
方法
2.1.1. synchronized
关键字的继承性
synchronized
关键字是不能继承的 父类的 synchronized
方法在子类中并不是 synchronized
子类需要显式地为某个方法加 synchronized
,以变成同步方法
2.1.2. synchronized
实例对象方法
synchronized
method(){}的 监视器对象是这个实例对象 加锁的对象不是这个方法,而是实例对象
有多个线程去访问 foo.mothodA()
时,同时只有一个线程能访问 foo
的 mothodA()
方法
一个类的实例对象有多个 synchronized
的方法时,只要一个线程访问了其中一个 synchronized
方法,其它线程就不能访问这个对象中的任何一个 synchronized
方法
不同实例对象间的 synchronized
方法调用时互不影响的
Foo foo1 = new Foo();Foo foo2 = new Foo();
不同的线程分别访问 foo1
、 foo2
中的 synchronized mothodA()
方法是互不影响的,因为它们的监视器对象分别是 foo1
、 foo2
同一个监视器对象才会阻塞同步
2.1.3 synchronized
static 静态方法
synchronized static staticMethodA()
的监视器对象是 Foo.class
类,所有访问这个类的静态同步方法的线程,都在同一个 Foo.class
上加锁和解锁,所以对所有线程中的类实例对象的同步起作用。
class Foo { public synchronized static methodA(); public synchronized static staticMethodA();
一个线程里调用了 Foo.staticMethodA()
会对其它线程调用 foo.methodA()
造成同步
2.2 synchronized
代码块
-
多个并发线程访问一个对象的
synchronized(this)
同步代码块时,同一时间只有一个线程执行 -
当一个线程访问一个对象的
synchronized(this)
同步代码块时,其它线程仍然可以访问这个对象的非synchronized(this)
代码块 而对对象中其它所有的synchronized(this)
同步代码块的访问都将被阻塞
class Foo { public void methodA()
public class Foo extends Thread{ private int val; //全局
3. Object类的wait、notify、notifyAll
/**
4.高级实用工具
4.1 java.util.concurrent.locks
中的API
锁可在对象之间传递 因此使用更灵活
4.2 java.util.concurrent.Semaphore
信号量
可以创建一个 new Semaphore(0)
零个许可的信号量作为一个阻塞点,另一个工作线程处理完一定的工作后 release()
释放一个许可出来,让前面阻塞的线程继续执行
4.3 java.util.concurrent.CountDownLatch
倒数闸门
4.4 java.util.concurrent.CyclicBarrier
循环屏障
4.5 java.util.concurrent.Exchanger<V>
对象交换器
适用于两个线程需要交换数据的场景。
-
只能有2个线程交换数据
-
exchange是交换点,另一线程未到达则本线程再次等待
-
各自线程exchange函数的返回值是另一线程exchange的参数值
public class FillAndEmpty{
分布式专题
高性能专题
大家可以点击加入群:606187239【JAVA大牛学习交流】里面有Java高级大牛直播讲解知识点 走的就是高端路线 (如果你想跳槽换工作 但是技术又不够 或者工作上遇到了 瓶颈 我这里有一个JAVA的免费直播课程 讲的是高端的知识点基础不好的误入哟 只要你有1-5年的开发经验可以加群找我要课堂链接 注意:是免费的 没有开发经验误入哦)