2015-01-31 5 views
0

저는 내가 설계 한 매트릭스/그리드 데이터 구조의 복제 된 복사본에 대해 폭/깊이 우선 검색 알고리즘을 적용하는 두 개의 별도 Swing Canvas 개체를 생성하는 학교 프로젝트에 참여하고 있습니다.자바 스레드가 별도의 개체에서 실행되고 있지 않습니다.

Matrix/Grid를 그래픽으로 변환하는 데 도움이되는 몇 가지 클래스를 만들었습니다.이 클래스는 애니메이션을 관리하기위한 ViewController 역할을하는 SearchAnimation 클래스에서 결합됩니다. 아래 이미지에서 오른쪽 (노란색 배경 영역이 아님)에 나타납니다. 각 SearchAnimation 객체에는 JLabel, Canvas 및 White Background가 포함됩니다. 는 enter image description here

JFrame를가 응용 프로그램 컨트롤러 클래스에서 SearchAnimation 클래스 (ICL.java)의 두 인스턴스를 포함 아래

레이아웃의 스크린 샷이다. 이러한 애니메이션은 동시에 실행해야합니다.

if (source == labelComponents) { 
      if (DEBUG && DEBUG_CLICK_LISTENER) System.out.println("\"Label Components\" Button Clicked!"); 
      /*This is where the call for the labelBreadth and labelDepth of the 
      ICLLogic class is going to occur*/ 

      // Run Animation 
      // Set Up Threads 
      System.out.println("ICL.ActionPerformed - Current Thread: " + Thread.currentThread()); 
      //mBreadthThread = new Thread(mBreadthAnimation, "Breadth Animation"); 
      //mDepthThread = new Thread(mDepthAnimation, "Depth Animation"); 

      // Start Threads 
      mBreadthThread.start(); 
      mDepthThread.start(); 
     } 
:

public void setupDepthFirstPanel() { 
      // Create a new GridGraphic Panel 
      //canvasDepthFirst = new GridPanel(null, DEPTH_FIRST_LABEL); 
      mDepthAnimation = new SearchAnimation(null, SearchAnimationType.DEPTH_FIRST_ANIMATION); 
      mDepthThread = new Thread(mDepthAnimation, "Depth Thread"); 
     } 

     public void setupBreadthFirstPanel() { 
      // Create a new GridGraphic Panel 
      //canvasBreadthFirst = new GridPanel(null, BREADTH_FIRST_LABEL); 
      mBreadthAnimation = new SearchAnimation(null, SearchAnimationType.BREADTH_FIRST_ANIMATION); 
      mBreadthThread = new Thread(mBreadthAnimation, "Breadth Thread"); 
     } 

나는 "레이블 구성 요소"라고 표시된 버튼의 클릭 이벤트에 응답 된 ActionListener 클래스의 스레드를 시작합니다 나는 그것을 별도의 SearchAnimation 객체를 전달, 각 애니메이션에 대해 별도의 스레드를 만들었습니다

프로그램이 실행되고 "레이블 구성 요소"버튼을 클릭하면 그래픽 중 하나만 애니메이션으로 시작되지만 애니메이션이 논리를 따르지 않으므로 두 SearchAnimation 스레드가 단일 JPanel/Canvas 내에서 실행되는 것처럼 보입니다. 어느 알고리즘이든. 내가 코멘트 대체 (alternate) 때

public void determineSearchType(Pixel p) { 
    // Animate a single pixel movement, step depends on AnimationType 
    if (DEBUG && DEBUG_STEP_NEXT_PIXEL) { System.out.println("Determining Animation Type..."); } 
    switch (mAnimationType) { 

     case BREADTH_FIRST_ANIMATION: 
      if (DEBUG && DEBUG_STEP_NEXT_PIXEL) { System.out.println("Animation Type: Breadth-First"); } 
      // Begin Breadth-First Search 
      stepBreadthSearch(p); 
      break; 

     case DEPTH_FIRST_ANIMATION: 
      if (DEBUG && DEBUG_STEP_NEXT_PIXEL) { System.out.println("Animation Type: Depth-First"); } 
      // Begin Depth-First Search 
      stepDepthSearch(p); 
      //simpleDepthSearch(mCurrentPixel); 
      break; 
    } 
} 

: 결국 적절한 알고리즘을 선택하는 열거에 전환 determineSearchType()를 호출

// THREAD METHODS 
    /** Implementation of the Runnable interface for Multithreading of the 
    * SearchAnimation Class, which allows multiple SearchAnimations to run Concurrently. 
    * In this case, the Breadth & Depth-First SearchAnimations 
    * 
    */ 
    public void run() { 
     System.out.println("Thread Started - " + mAnimationType.toString()); 

     // Run the Animation 
     step(); 

    } 

: 여기

는 SearchAnimation 내에서 실행 가능한 인터페이스의 구현입니다 그 (것)들 밖으로, 각 실/Animation는 그것의 자신의 JPanel/Canvas 도표에서 실행하고 예상 한 결과를 가져온다. 나는 스레딩에 상당히 익숙하며 누군가가 쉬운 해결책을 가지고 있다고 확신한다. 애니메이션이 동시에 움직이지 않는다는 문제를 해결할 수있는 방법에 대한 아이디어가 있습니까?

+3

슬프게도, 스윙은 절대적으로 ** 아닙니다 ** threadsafe입니다. ** 절대적으로 ** 여러 스레드에서 Swing 객체에 액세스 할 수 없습니다. ** ** 결과는 예측할 수없는 결과입니다. Swing 객체 **와의 모든 상호 작용은 ** EDT에서 발생해야합니다. –

+0

별도의 참조 및 속성 값을 가진 별도의 인스턴스 인 경우에도? 클래스는 이러한 스윙 개체를 확장합니다. – Matt

+0

상관 없어요. 스윙은 EDT에서 일어나야합니다. 마침표.백그라운드 작업을 수행하려면 [Swing workers] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html)를 사용해야합니다. –

답변

-1

옵션 1 :

다른 스레드 기회를 제공하기 위해 실행합니다. 스레드 코드의 끝에서, yield()을 시도하고 당신은 약간의 행운을 가지고 있는지

Thread.currentThread().yield(); 

옵션 2 : 스레드에서

추가 플래그가 일시 중지 및 스레드를 계속합니다. 아이디어는

스레드를 완료 한 후 - 스레드 1을 일시 중지 한 다음 스레드 2를 시작하고 스레드 2를 완료 한 후 - 스레드 2를 일시 중지하고 스레드 1을 다시 계속합니다.

관련 문제