2013-08-06 2 views
2

내 코드에서 발생해서는 안되는 스레드 문제가 있습니다. 그래서 나는 약간의 문제를 해결하려고 노력하고있다. 내가 할 수있는 나는이 간단한 코드 내 문제를 설명하려고합니다 - 나는 문제가 발생하고있어 코드가 크고 매우 짧은 코드의 복잡하기 때문에 :자바 동시성 - 동기화 된 블록

이가가는 경우
................... 
.................. 
void createAndRunThreads(){ 
    List<Path> pathList = //read path from DB readPath(); 
    for(Path p : pathList){ 
     RunJob rj = new RunJob(p); 
     Thred t = new Thread(rj); 
     t.start(); 
    } 
} 

class RunJob implements Runnable { 
    private Path path; 
    private ExecuteJob execJob; 

    public RunJob(Path path){ 
     this.path = path; 
     this.execJob = new ExecuteJob(); 
    } 

    public void run() { 
     execJob.execute(path); 
    } 

} 

class ExecuteJob { 

    private static Job curentExecutingJob; 

    public void execute(Path path){ 
     //here every thread should get different job list from others but this is not happening 
     //so what happens eventually two threads are executing the same Job at once and it gets messy 
     List<Job> jobList = getJobsFromPath(path); 

     for(Job job : jobList) { 
     curentExecutingJob=job; 

     //work around that I'm trying to do. So if other thread tries to run the same job has to wait on lock(I dont know if this is posible do) 
     synchronized(curentExecutingJob){ 
      if(job.getStatus.equals("redy")){ 
       //do sum initialization 
       //and databese changes 
       job.run(); 
      } 
     } 
     } 
    } 

} 

그래서 내 관심사입니다 작업 - 잠금 개체를 메모리 (정확한 개체 여야 함) 또는 equals (동일한 개체를 구현할 때)로 비교하면 알 수 없음

정적 curentExecutingJob 구성원에 하나의 값 개체가있는 경우 어떻게됩니까? 첫 번째 스레드 및 그 (동기화 된 블록)에 대한 잠금을 생성하고 두 번째 스레드는 그 값을 변경하고 동기화 된 블록을 입력하려고합니다. (내가 기대하고있는 나의 기대는 스레드 2가 실행과 onl과 함께 계속된다는 것입니다. 그는이 방법을 수행 할 수 있는지 모르겠어요 이전에 첫 번째 스레드가있어 DB)

에서 같은 작업을 얻고 감에게 있습니다

두 스레드를 가지고 할 때 블록이 될 것이라고 Y 시간은 방법 안에 다음 코드를 실행

1 Job j = getJobByIdFromDB(1111); 
2 if(j.status.equals("redye")){ 
3  do staff 
4  make database changes 
5  j.run(); 
6  j.state="running"; 
7 } 

ThreadA은 JVM에서 라인 (3)의 실행에서 정지하고 그 상태로 실행 가능한 실행 변경되고 폴링에서 대기하도록 설정된다.

ThreadB는 JVM에서 기회가 주어지고 ThreadB는 발생하지 않으려는 행 1, 2, 3, 4, 5, 6을 실행합니다. 나는 나머지 스레드의 누군가가 같은 코드를 입력 할 기회를 갖기 전에 라인 2,3에서 코드를 입력하는 첫 번째 스레드를 원한다.

문제는 두 스레드가 다른 인스턴스와 함께 예제 메소드를 실행하므로 동기화 된 전체 메서드가 작동하지 않습니다 - 또한이 메서드에서 실행 된 다른 코드가 있고 동기화 할 수 싶지 않아
그래서 내 문제에 대한 솔루션이 있습니다 또한 동기화 할 경우 (this.class) {} 멀티 스레딩의 이점과 감각을 잃을 것입니다.

+0

우선, 변수 curentExecutingJob은 정적으로 선언되며 동시에 덮어 쓰여지고 액세스됩니다. 이 접근법은이 방법이 실제로 좋지 않습니다. 이 계획으로 무엇을 성취하기를 기대합니까? – Martin

+0

ExecutorService를 고려해 보셨습니까? 그것은 큐가있는 스레드 풀이며 각 스레드가 하나의 스레드에서만 실행되도록합니다. –

답변

0

답변을 드릴 것입니다. 죄송합니다.

블록

동기 (curentExecutingJob)

이 (당신의 측면에서 메모리) 객체 curentExecutingJob에 동기화됩니다. otherExecutingJob을 currentExecutingJob.equals (otherExecutingJob) == true로 동기화하면 다른 두 동기화 문이 서로 영향을 미치지 않습니다.

질문/문제 : getJobsFromPath가 수행 중이거나 수행해야하는 작업, 실제로 수행하려는 작업 및 실제로 발생한 문제점을 설명하면 도움이됩니다. 그것은 나에게 분명하지 않습니다.

+0

나는 그가 동일한 객체를 실제로 변경하는 스레드를 동기화하고 거기서 약간의 문제를 일으키고 싶다고 생각한다. 동일한 객체를 편집하여 어떤 순서로 동기화하려고 할 때 모든 스레드를 동기화하려고한다. –

0

나는 그것을 준비인지 아닌지는 내가이 대신 Runnable를

의 호출 인터페이스를 사용할 수있는 afeasible 방법

아니라고 생각뿐만 아니라, 작업의 상태에 대한의를 확인하는 것이 코드를 보았다

여기에 자세한 예시가 나와 있습니다.

Java Concurrency

1

문제는 'currentExecutingJob가'ExecuteJob의 모든 인스턴스는이 변수의 동일한 '예'를 공유하는 것을 의미 정적으로 정의된다는 점이다. 또한이 변수의 값을 동기화 블록 외부에 설정하면 각 스레드가 제어 할 수없는 방식으로 설정합니다. 다음 동기화 블록은 실제적인 영향을 전혀 미치지 않아야합니다.

예제 코드가 작성된 것처럼 여러 스레드에서 공유되는 리소스가 없기 때문에 정적 변수가 필요하지 않으며 동기화가 필요하지 않은 것처럼 보입니다.

그러나 코드의 주석은 두 스레드가 동시에 같은 작업을 실행하지 못하게하려는 것을 나타냅니다. 동일한 작업이 실행 중인지 여부를 확인하기 위해 실행중인 작업을 비교하지 않았고 비교가 있더라도 getJobsFromPath()는 동일한 객체 인스턴스 (예 : 두 스레드/경로가 동일한 '작업'을 만났을 때 재사용해야합니다.

코드에이 내용이 표시되지 않습니다.