클래스 잠금과 개체 잠금이 충돌하나요? 객체 잠금과 개인 잠금이 충돌합니까? 예를 통해 설명하세요.
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 중국어 웹사이트를 주목하세요!