코루틴간에 데이터를 순차적으로, 동기적으로 교환할 수 있는 통로를 뜻한다. 자바의 BlockingQueue와 비슷하지만 채널은 suspend를 통해 통신한다.
채널은 shared mutable state 없이 효과적으로 코루틴 간에 통신이 가능하다.

구조화된 접근 방식을 제공해주기에 데이터 이동, 공유 자원 관리 등에 이점이 있으며
비동기 처리 시에도 유연하고 직관적인 관리 방안을 제공해준다. 채널을 활용하면 코루틴간의 복잡한 협력관계 처리, 코루틴 간의 데이터 플로우 관리, 복수의 코루틴 동기화 처리도 가능하다.
그리고 suspend 함수를 채널과 같이 사용하는 것 만으로도 간단하게 처리해줄 수 있다.
Channel(capacity) 팩토리는 capacity값에 따라서 채널의 종류가 달라진다.
val channel = Channel<String>()
rendezvous 채널로 생성, 해당 채널은 버퍼가 없으며 데이터는 send 와 receive의 호출이 한번 맞았을때 (rendezvous)때만 옮겨간다.
Channel.UNLIMITED 인 경우무제한 버퍼로 생성, 해당 채널은 linked-list 버퍼로 무제한 버퍼가 생성된다.
send 가 suspend 함수는 일시정지 안되고 trySend는 항상 성공한다.
Channel.CONFLATED 인 경우conflated 채널로 생성, 해당 채널의 버퍼는 collectLatest처럼 항상 마지막 값만 보낸다.
// Sending data to the channel
channel.send("Hello, Kotlin!")
// Receiving data from the channel
val message = channel.receive()
공유된 채널에 대해서 동시에 접근하는 것은 조심해서 사용해야하며 race condition과 데이터 손실을 예방하기 위해 적절한 동기화 메커니즘을 추가해야한다.
채널 작업의 완료를 기다리는동안 코루틴을 블럭하는 경우 데드락이 발생할 수 있다.
채널이 더 이상 사용이 불가능해질 때 코루틴이 블락당하지않도록 채널 클로저에 적절한 핸들링을 해줘야한다.
Mutex, Semaphore같은 locking 메커니즘을 사용
에러 복구 메커니즘, 여러 영역에 대한 에러 핸들링을 권장
공유된 채널의 생성 및 파괴를 적절하게 관리해줘야한다. 채널 closure 이벤트에서 코루틴 관리를 해줘야한다.