간단한 enq는 동시성과 아무 관련이 없으며 단지 이중 연결 목록을 설정하는 것뿐입니다. Java의 연결 목록은 C++의 연결 목록과 다르지 않습니다. 단, Java가 포인터를 참조로 캡슐화한다는 점만 제외하면 실제로 여전히 포인터 역할을 합니다. 노드 t는 새로 삽입된 노드의 이전 노드로 추상적으로 볼 수 있습니다. 당연히 대기열의 끝에 새 노드가 삽입됩니다. 그래서 노드 t = 꼬리. 빈 대기열의 상황을 무시하고 노드가 대기열에 합류하면 새 노드의 이전 및 다음이 먼저 처리되어야 하므로 node.pre = tail; node.next = null; 그런 다음 이전 노드의 다음 노드를 새 노드, 즉 t.next = node로 지정합니다. 다음으로, 빈 큐를 고려해보세요. 여기서 큐는 new Node()로 강제 초기화됩니다. 이때 tail == head. 새로 삽입된 노드를 삽입하지 않는 이유는 직관적으로 compareAndSetHead(node)가 더 일반적입니다. 물론 싱글 스레드 큐처럼 바로 이전 값과 다음 값을 변경하지는 않지만, comapreAndSet* 함수에 캡슐화되어 있습니다. 여기서는 제외를 유지해야 합니다.
@dj Zheng Doujiu 이것이 맞는지 아닌지는 모르겠습니다. 디버그 기반으로 설계되었으므로 노드 대신 t가 출력됩니다. 이런 의미도 표현하시는지 모르겠네요
간단한 enq는 동시성과 아무 관련이 없으며 단지 이중 연결 목록을 설정하는 것뿐입니다. Java의 연결 목록은 C++의 연결 목록과 다르지 않습니다. 단, Java가 포인터를 참조로 캡슐화한다는 점만 제외하면 실제로 여전히 포인터 역할을 합니다.
노드 t는 새로 삽입된 노드의 이전 노드로 추상적으로 볼 수 있습니다. 당연히 대기열의 끝에 새 노드가 삽입됩니다. 그래서 노드 t = 꼬리. 빈 대기열의 상황을 무시하고 노드가 대기열에 합류하면 새 노드의 이전 및 다음이 먼저 처리되어야 하므로 node.pre = tail; node.next = null; 그런 다음 이전 노드의 다음 노드를 새 노드, 즉 t.next = node로 지정합니다. 다음으로, 빈 큐를 고려해보세요. 여기서 큐는 new Node()로 강제 초기화됩니다. 이때 tail == head. 새로 삽입된 노드를 삽입하지 않는 이유는 직관적으로 compareAndSetHead(node)가 더 일반적입니다.
물론 싱글 스레드 큐처럼 바로 이전 값과 다음 값을 변경하지는 않지만, comapreAndSet* 함수에 캡슐화되어 있습니다. 여기서는 제외를 유지해야 합니다.
하, 지금은 그 enq 방식을 이해하지 못하실 수도 있겠네요. 구체적으로 배우지 않았다면 이해하는 사람이 많지 않을 것 같아요. 잠금 없는 동기화를 배우는 것은 멀티스레딩의 매우 고급 부분입니다.