Необходимо смотреть на то, как парни по getdropbox.com делают это для своего клиентского программного обеспечения, включая Linux. Это довольно хитро для взламывания и требует, чтобы некоторое довольно творческое дизассемблирование закончило механизмы защиты.
Это навязано графической структурой, которая часто (но не всегда) предоставляется операционной системой.
По сути, делать все «должным образом потокобезопасным» неэффективно. Хотя маршалировать вызовы обратно в поток пользовательского интерфейса определенно сложно, это позволяет самому потоку пользовательского интерфейса обрабатывать события чрезвычайно быстро, не беспокоясь о блокировках и т. Д.
Делать весь UI потокобезопасным было бы очень дорого (медленно). Лучше возложить на программиста бремя синхронизации в (относительно редком) случае, когда потоку необходимо обновить пользовательский интерфейс.
Это потому, что инфраструктура пользовательского интерфейса была разработана таким образом. Теоретически возможно разработать структуру пользовательского интерфейса, которая будет по-настоящему многопоточной, но трудно избежать взаимоблокировок.
Грэм Гамильтон написал хорошую статью об этом со ссылкой на Swing, основную структуру пользовательского интерфейса Java.