>  기사  >  Java  >  Java 클래스 잠금, 개체 잠금, 개인 잠금 충돌 테스트

Java 클래스 잠금, 개체 잠금, 개인 잠금 충돌 테스트

高洛峰
高洛峰원래의
2017-01-19 13:41:401248검색

클래스 잠금과 개체 잠금이 충돌하나요? 객체 잠금과 개인 잠금이 충돌합니까? 예를 통해 설명하세요.

1. 관련 합의

다음 설명을 명확히 하기 위해 먼저 이 기사에 관련된 잠금의 관련 정의에 대해 다음과 같이 합의합니다.

1. 잠금: 코드에서 코드의 메소드에 정적 및 동기화 잠금을 추가하거나 아래의 increament()와 같은 동기화(xxx.class) 코드 세그먼트를 추가합니다.

2. 코드 잠금 또는 아래의 synOnMethod() 및 synInMethod()와 같은 동기화된(this) 코드 세그먼트에서

3. 개인 잠금: 클래스 내부에 개인 개체 잠금과 같은 개인 속성을 선언하고 잠금을 해제합니다. 필요할 때 사용하세요. 아래의 synMethodWithObj()와 같은 코드 세그먼트는 동기화(잠금)됩니다.

2. 테스트 코드

1. 시작 클래스 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. 동기화 메서드를 시작하는 스레드 클래스 ObjThread를 작성합니다. 다양한 테스트에 맞게 조정)

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. 다양한 잠금 방법을 포함하는 LockTestClass 작성

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. 테스트 결과

1. 클래스 잠금 및 객체 테스트 lock. ObjectThread의 run 메소드를 다음과 같이 수정합니다.

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();
 }

터미널 출력:

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.

객체 잠금 방식(synInMothod)이 클래스 잠금 방식보다 낫다는 것을 알 수 있습니다. (increament)는 2초 더 빠릅니다. 이는 increation이 synInMehtod를 실행하기 전에 2초 동안 대기하고 이 두 메서드가 동일한 스레드를 공유하므로 실행 시 increament가 2초 더 느려지기 때문입니다. , 첫 번째 시작되면 2초 더 빠르게 증가합니다.

클래스 잠금 방법이 시작되면 다른 스레드의 개체 잠금 방법도 거의 동시에 시작됩니다. 이는 두 스레드가 동일한 잠금을 사용하지 않으며 경쟁이 없음을 나타냅니다.

결론: 클래스 잠금과 개체 잠금은 경쟁하지 않으며 잠금 방법도 서로 영향을 미치지 않습니다.

2. Private 잠금 및 개체 잠금, ObjectThread의 실행 메서드는 다음과 같이 수정됩니다.

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();
 }

터미널 출력:

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

클래스 잠금 및 개체와 매우 유사합니다. 잠그다.

결론: 개인용 잠금 장치와 개체 잠금 장치는 경쟁하지 않으며 잠금 방법도 서로 영향을 미치지 않습니다.

3. 동기화는 메소드에 직접 추가되고 동기화됩니다(this). ObjectThread의 실행 메소드는 다음과 같이 수정됩니다.

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();
 }

터미널 출력:

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

엄격하게 직렬 출력을 모두 확인하십시오(물론 잠금을 획득한 사람에 따라 다시 실행할 때 synInMethod 또는 synOnMethod가 먼저 실행되는지 여부는 결정되지 않습니다).

결론: 동기화된 메서드에 직접 추가된 것과 동기화된(this) 두 가지 잠금 메서드는 경쟁 관계에 있으며 동시에 하나의 메서드만 실행할 수 있습니다.

Java 클래스 잠금, 개체 잠금, 개인 잠금 충돌 테스트와 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.