2013-04-09 3 views
1
package demo5; 

class Process extends Thread { 

static int counter = 0; 

public static synchronized void increment() { counter++; } 

public void run() { 
    for (int i = 0; i < 1000000; i++) 
    { 
     increment(); 
    } 
    System.out.println("Done."); 
    } 
} 

public class App { 

public static void main(String[] args) throws InterruptedException { 
    Process p1 = new Process(); 
    Process p2 = new Process(); 
    p1.start(); 
    p2.start(); 

    p1.join(); 
    p2.join(); 

    System.out.println("Value of count is :" + p1.counter); 

} 

} 

증가 기능을 NON-STATIC 함수로 선언하면 끝에있는 카운터의 값은 2 백만이되지 않습니다. 반면에 증분 방법이 정적으로 정의되면기본 멀티 스레딩 문제

이 제대로 작동합니다.

내가 아는 한 모든 프로세스 개체에 대해 하나의 증가 함수 만있을 것입니다. 그렇다면 정적 메서드로 선언해야하는 이유는 무엇입니까?

감사는 정적 synchronized가 Process.class 인스턴스에 고정하게됩니다 선언

+0

'카운터'가 '정적'이라고 확신 하시겠습니까? – zneak

+0

카운터에 임시 키워드를 추가하고 동기화를 삭제해도 작동합니다. – shevchyk

+0

@shevchik Transient는 영향을 미치지 않습니다. 휘발성을 의미합니까? 심지어 그때 그것은 작동하지 않을 것이다. –

답변

7

. 따라서 실행중인 모든 스레드는 increment 메서드 내의 Object에서 차단됩니다. 정적을 제거하면 각 스레드는 Thread 인스턴스에서만 차단됩니다 (이 경우 스레드 인스턴스는 두 개가됩니다).

결과적으로 counter 변수가 병렬로 증분되고 여러 번 언급 한 것처럼 int 증가는 스레드로부터 안전하지 않습니다.

As far as I know there will be only ONE increment function for all the Process objects

가 Process 클래스에 대한 하나 개 증가 기능이지만, 동기화가 인스턴스에 대한 방법을 개체에서 수행되지 않고는 :

class Process{ 
    public void increment() { 
      synchronized(this){ 
        counter++; 
      } 
} 
:

class Process{ 
    public synchronized void increment() { counter++; } 
} 

에 equivallent인가

편집 : Rouki 님의 질문에 답변했습니다.

class Process{ 
    public static synchronized void increment() { counter++; } 
} 

class Process{ 
    public void increment() { 
      synchronized(Process.class){ 
        counter++; 
      } 
} 
+0

감사합니다. – Rouki

+0

흠, 컴파일러가 생성 된 각 객체에 대해 모든 클래스 멤버 함수를 생성한다고 알려주시겠습니까? (Java에 새로 온 것, 전에 cpp에서 개발 된) – Rouki

+0

@Rouki 혼란스럽게해서 죄송합니다. –

1
당신은 AtomicInteger 카운터와 INT 카운터를 대체 할 수 있습니다

에 equivallent - 당신은이 방법에서 동기화 된 키워드를 제거 할 수 있습니다 이런 식으로하고,이 경우 문제가되지해야한다 메서드는 정적 또는 인스턴스 메서드입니다.