Home  >  Article  >  Java  >  Java class lock, object lock, private lock conflict testing

Java class lock, object lock, private lock conflict testing

高洛峰
高洛峰Original
2017-01-19 13:41:401248browse

Will class locks and object locks conflict? Will object locks and private locks conflict? Explain through examples.

1. Relevant conventions

In order to clarify the following description, we first make the following conventions on the relevant definitions of locks involved in this article:

1. Class lock: in the code Add static and synchronized locks to the methods in the code, or synchronized (xxx.class) code segments, such as increament() below;

2. Object lock: Add synchronized to the methods in the code lock, or synchronized(this) code segment, such as synOnMethod() and synInMethod() below;

3. Private lock: Declare a private property such as private Object lock inside the class, and lock it when needed The code segment synchronized(lock), such as synMethodWithObj() below.

2. Test code

1. Write a startup class ObjectLock

public class ObjectLock {
 public static void main(String[] args) {
  System.out.println("start time = " + System.currentTimeMillis()+"ms");
  LockTestClass test = new LockTestClass();
  for (int i = 0; i < 3; i++) {
   Thread thread = new ObjThread(test, i);
   thread.start();
  }
 }
}

2. Write a thread class ObjThread to start the synchronization method (note that its run method may Will be adjusted for different tests)

public class ObjThread extends Thread {
 LockTestClass lock;
 int i = 0;
 public ObjThread(LockTestClass lock, int i) {
  this.lock = lock;
  this.i = i;
 }
 public void run() {
  //无锁方法
//  lock.noSynMethod(this.getId(),this);
  //对象锁方法1,采用synchronized synInMethod的方式
  lock.synInMethod();
  //对象锁方法2,采用synchronized(this)的方式
//  lock.synOnMethod();
  //私有锁方法,采用synchronized(object)的方式
//  lock.synMethodWithObj();
  //类锁方法,采用static synchronized increment的方式
  LockTestClass.increment();
 }
}

3. Write a lock test class LockTestClass, including various locking methods

public class LockTestClass {
 //用于类锁计数
 private static int i = 0;
    //私有锁
 private Object object = new Object();
 /**
  * <p>
  * 无锁方法
  *
  * @param threadID
  * @param thread
  */
 public void noSynMethod(long threadID, ObjThread thread) {
  System.out.println("nosyn: class obj is " + thread + ", threadId is"
    + threadID);
 }
 /**
  * 对象锁方法1
  */
 public synchronized void synOnMethod() {
  System.out.println("synOnMethod begins" + ", time = "
    + System.currentTimeMillis() + "ms");
  try {
   Thread.sleep(2000L);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("synOnMethod ends");
 }
 /**
  * 对象锁方法2,采用synchronized (this)来加锁
  */
 public void synInMethod() {
  synchronized (this) {
   System.out.println("synInMethod begins" + ", time = "
     + System.currentTimeMillis() + "ms");
   try {
    Thread.sleep(2000L);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out.println("synInMethod ends");
  }
 }
 /**
  * 对象锁方法3
  */
 public void synMethodWithObj() {
  synchronized (object) {
   System.out.println("synMethodWithObj begins" + ", time = "
     + System.currentTimeMillis() + "ms");
   try {
    Thread.sleep(2000L);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out.println("synMethodWithObj ends");
  }
 }
 /**
  * 类锁
  */
 public static synchronized void increament() {
  System.out.println("class synchronized. i = " + i + ", time = "
    + System.currentTimeMillis() + "ms");
  i++;
  try {
   Thread.sleep(2000L);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
   System.out.println("class synchronized ends.");
 }
}

3. Test results

1 .Test the class lock and object lock. The run method of ObjectThread is modified as follows:

public void run() {
  //无锁方法
//  lock.noSynMethod(this.getId(),this);
  //对象锁方法1,采用synchronized synInMethod的方式
  lock.synInMethod();
  //对象锁方法2,采用synchronized(this)的方式
//  lock.synOnMethod();
  //私有锁方法,采用synchronized(object)的方式
//  lock.synMethodWithObj();
  //类锁方法,采用static synchronized increment的方式
  LockTestClass.increament();
 }

Terminal output:

start time = 1413101360231ms
synInMethod begins, time = 1413101360233ms
synInMethod ends
class synchronized. i = 0, time = 1413101362233ms
synInMethod begins, time = 1413101362233ms
class synchronized ends.
synInMethod ends
class synchronized. i = 1, time = 1413101364233ms
synInMethod begins, time = 1413101364233ms
class synchronized ends.
synInMethod ends
class synchronized. i = 2, time = 1413101366234ms
class synchronized ends.

You can see that the object lock method (synInMothod) is better than the class lock method when it is first started. (increament) is 2 seconds faster. This is because increament sleeps for 2 seconds before executing synInMehtod, and these two methods share the same thread, so it will be 2 seconds slower. If increament is placed in front of synInMethod in run, then the first It is increament 2 seconds faster when it starts up.

When the class lock method is started, the object lock method of another thread is also started almost at the same time, indicating that the two are not using the same lock and there will be no competition.

Conclusion: Class locks and object locks will not compete, and their locking methods will not affect each other.

2. Private locks and object locks, the run method of ObjectThread is modified as follows:

public void run() {
  //无锁方法
//  lock.noSynMethod(this.getId(),this);
  //对象锁方法1,采用synchronized synInMethod的方式
  lock.synInMethod();
  //对象锁方法2,采用synchronized(this)的方式
//  lock.synOnMethod();
  //私有锁方法,采用synchronized(object)的方式
  lock.synMethodWithObj();
  //类锁方法,采用static synchronized increment的方式
//  LockTestClass.increament();
 }

Terminal output:

start time = 1413121912406ms
synInMethod begins, time = 1413121912407ms.
synInMethod ends.
synMethodWithObj begins, time = 1413121914407ms
synInMethod begins, time = 1413121914407ms.
synInMethod ends.
synMethodWithObj ends
synInMethod begins, time = 1413121916407ms.
synMethodWithObj begins, time = 1413121916407ms
synInMethod ends.
synMethodWithObj ends
synMethodWithObj begins, time = 1413121918407ms
synMethodWithObj ends

is very similar to class locks and object locks.

Conclusion: Private locks and object locks will not compete, and their locking methods will not affect each other.

3.Synchronized is directly added to the method and synchronized(this). The run method of ObjectThread is modified as follows:

public void run() {
  //无锁方法
//  lock.noSynMethod(this.getId(),this);
  //对象锁方法1,采用synchronized synInMethod的方式
  lock.synInMethod();
  //对象锁方法2,采用synchronized(this)的方式
  lock.synOnMethod();
  //私有锁方法,采用synchronized(object)的方式
//  lock.synMethodWithObj();
  //类锁方法,采用static synchronized increment的方式
//  LockTestClass.increament();
 }

Terminal output:

start time = 1413102913278ms
synInMethod begins, time = 1413102913279ms
synInMethod ends
synInMethod begins, time = 1413102915279ms
synInMethod ends
synOnMethod begins, time = 1413102917279ms
synOnMethod ends
synInMethod begins, time = 1413102919279ms
synInMethod ends
synOnMethod begins, time = 1413102921279ms
synOnMethod ends
synOnMethod begins, time = 1413102923279ms
synOnMethod ends

You can see that both Strictly serial output (of course it is not determined whether synInMethod or synOnMethod is run first when executing again, depending on who obtained the lock).

Conclusion: synchronized directly added to the method and synchronized(this) both lock the current object. The two locking methods are in a competitive relationship, and only one method can be executed at the same time.

For more articles related to Java class locks, object locks, and private lock conflict tests, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn