Java对象锁
作者:网络转载 发布时间:[ 2016/12/28 9:55:12 ] 推荐标签:测试开发技术 Java 锁
在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制。
1.对象的锁
所有对象都自动含有单一的锁。
JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。
只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁。
每当任务离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务可以使用此资源。
2.synchronized同步块
2.1同步到单一对象锁
当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务(线程)只能互斥的进入这些同步块。
Resource1.java演示了三个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中,虽然这些同步块处在不同的方法中,但由于是同步到同一个对象(当前对象synchronized(this)),所以对它们的方法依然是互斥的。
Resource1.java
packagecom.zj.lock;
importjava.util.concurrent.TimeUnit;
publicclassResource1 {
publicvoidf() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in f()");
synchronized(this) {
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in f()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicvoidg() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in g()");
synchronized(this) {
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in g()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicvoidh() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in h()");
synchronized(this) {
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in h()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicstaticvoidmain(String[] args) {
finalResource1 rs =newResource1();
newThread() {
publicvoidrun() {
rs.f();
}
}.start();
newThread() {
publicvoidrun() {
rs.g();
}
}.start();
rs.h();
}
}
结果:
Thread-0:not synchronized in f()
Thread-0:synchronized in f()
main:not synchronized in h()
Thread-1:not synchronized in g()
Thread-0:synchronized in f()
Thread-0:synchronized in f()
Thread-0:synchronized in f()
Thread-0:synchronized in f()
Thread-1:synchronized in g()
Thread-1:synchronized in g()
Thread-1:synchronized in g()
Thread-1:synchronized in g()
Thread-1:synchronized in g()
main:synchronized in h()
main:synchronized in h()
main:synchronized in h()
main:synchronized in h()
main:synchronized in h()
2.2同步到多个对象锁
Resource1.java演示了三个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中,这些同步块处在不同的方法中,并且是同步到三个不同的对象(synchronized(this),synchronized(syncObject1),synchronized(syncObject2)),所以对它们的方法中的临界资源访问是独立的。
Resource2.java
packagecom.zj.lock;
importjava.util.concurrent.TimeUnit;
publicclassResource2 {
privateObjectsyncObject1=newObject();
privateObjectsyncObject2=newObject();
publicvoidf() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in f()");
synchronized(this) {
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in f()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicvoidg() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in g()");
synchronized(syncObject1) {
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in g()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicvoidh() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in h()");
synchronized(syncObject2) {
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in h()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
publicstaticvoidmain(String[] args) {
finalResource2 rs =newResource2();
newThread() {
publicvoidrun() {
rs.f();
}
}.start();
newThread() {
publicvoidrun() {
rs.g();
}
}.start();
rs.h();
}
}
结果:
Thread-0:not synchronized in f()
Thread-0:synchronized in f()
main:not synchronized in h()
main:synchronized in h()
Thread-1:not synchronized in g()
Thread-1:synchronized in g()
Thread-0:synchronized in f()
main:synchronized in h()
Thread-1:synchronized in g()
Thread-0:synchronized in f()
main:synchronized in h()
Thread-1:synchronized in g()
Thread-0:synchronized in f()
main:synchronized in h()
Thread-1:synchronized in g()
Thread-0:synchronized in f()
main:synchronized in h()
Thread-1:synchronized in g()
3.Lock对象锁
除了使用synchronized外,还可以使用Lock对象来创建临界区。Resource3.java的演示效果同Resource1.java;Resource4.java的演示效果同Resource2.java。
Resource3.java
packagecom.zj.lock;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;
publicclassResource3 {
privateLocklock=newReentrantLock();
publicvoidf() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in f()");
lock.lock();
try{
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in f()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}finally{
lock.unlock();
}
}
publicvoidg() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+":not synchronized in g()");
lock.lock();
try{
for(inti = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+":synchronized in g()");
try{
TimeUnit.SECONDS.sleep(3);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}finally{
lock.unlock();
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11