2014-12-06 4 views
1

Frame이 내 목록 항목 인 LinkedList를 선언했습니다.개체가 목록에 포함되어 있으면 LinkedList.indexOf()가 -1을 반환하는 이유는 무엇입니까?

private LinkedList<Frame> linkedList = new LinkedList<Frame>(); 

목록에 쿼리 된 항목이 포함되어 있어도 indexOf -1을 테스트하면 반환된다는 것을 알았습니다. 문서에는 "(...) 또는이 목록에 요소가 없으면 -1이 표시됩니다." 이러한 이상한 결과에서

https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#indexOf(java.lang.Object)

봐 :

linkedList.size() -> 1 
linkedList.get(0) -> frame 
linkedList.contains(linkedList.get(0)) -> false 
linkedList.indexOf(linkedList.get(0)) -> -1 

가 난 아무것도 바라나요? 무슨 일이야?

동기화없이 여러 스레드에서 목록에 액세스하고 있습니다. 이로 인해 문제가 발생했을 수 있습니까?

-

로그 (아래 참조) :

12-05 20:30:00.101 16446-16461/cc.closeup I/System.out﹕ **** TEST    0 
12-05 20:30:00.301 16446-16476/cc.closeup I/System.out﹕ **** TEST    -1 
12-05 20:30:00.856 16446-16461/cc.closeup I/System.out﹕ **** TEST    0 
12-05 20:30:01.051 16446-16476/cc.closeup I/System.out﹕ **** TEST    -1 
12-05 20:30:01.601 16446-16461/cc.closeup I/System.out﹕ **** TEST    0 
12-05 20:30:01.801 16446-16476/cc.closeup I/System.out﹕ **** TEST    -1 
12-05 20:30:02.356 16446-16461/cc.closeup I/System.out﹕ **** TEST    0 
12-05 20:30:02.551 16446-16476/cc.closeup I/System.out﹕ **** TEST    -1 
12-05 20:30:03.101 16446-16461/cc.closeup I/System.out﹕ **** TEST    0 
12-05 20:30:03.301 16446-16476/cc.closeup I/System.out﹕ **** TEST    -1 
+2

'프레임'유형이 'equals (Object)'를 어떻게 구현합니까? –

+0

전혀 아닙니다. 구현해야합니까? –

+0

@OliverHausler 예, 그러면 내부적으로 만 점검하여 원하는 결과를 얻을 수 있습니다. –

답변

1

봐 조심스럽게 containsindexOf의의 javadoc에서. 메서드는 equals 메서드를 사용하여 요소가 컬렉션에 있는지 여부를 확인합니다.

containsindexOf는 "거기 아니다"라고하는 경우는 다음 목록에 존재하는 객체는 당신이 ... equals(Object)의 객체의 구현에 따라 테스트하는 것과 다른 하나입니다.


다른 가능성은 다른 스레드에서 컬렉션에 액세스/업데이트하고 있으며 제대로 동기화하지 못했다는 것입니다. 이로 인해 하나의 스레드가 목록의 부실하거나 일치하지 않는 버전을 볼 수 있습니다.

목록 자체를 동기화해도 괜찮습니까? 당신이 동기화 된 목록을 통해 모든 작업을 수행하고 반복자를 사용하지 않는 경우

Collections.synchronizedList(new LinkedList<>()) 

, 각 개인 작업은 스레드 안전 및 원자 될 것입니다. 그러나 : 당신이 동기화 할 일련의 작업을해야하는 경우이 문제가 해결되지 않는

  • 동기화되지 않은 "동기화 목록"의 반복자 및
  • 은/원자 적으로 실행. 예를 들어

: 항상 잠재적 인 예외의 결과로 현재의 크기, 크기 수있는 l.size()l.get(i) 통화 사이의 변화를 줄 것이다

List<Integer> l = Collections.synchronizedList(new LinkedList<>()); 

    // Make the list visible to other threads ... 

    for (int i = 0; i < l.size(); i++) { 
     Integer ii = l.get(i); 
     ... 
    } 

l.size() 동안.

요약하면 ... Collections.synchronizedList(...)은 목록과 관련된 모든 스레드 안전 문제에 대한 해결책이 아닙니다. 당신은 아직도 당신이하고있는 일에 대해 생각할 필요가 있습니다.

+0

"다른 스레드에서 컬렉션에 액세스/업데이트하고 올바르게 동기화하지 못했기 때문에 하나의 스레드에서 부실하거나 일관성없는 버전이 표시 될 수 있습니다. 목록의. " -> 이것은 정확하게 일어난 일입니다. –

+0

이미 답변되었지만 다른 스레드가 동일한 변수의 다른 버전을 어떻게 볼 수 있는지 잘 설명하는 링크가 있습니다 : http://tutorials.jenkov.com/java-concurrency/volatile.html - very 동시성에 대해서도 배우기에 좋다. –

관련 문제