erkennen, wenn ich schreiben würde:Wie ein Selector.wakeup Anruf
int selectedChannels = selector.select(); Set selectedKeys = selector.selectedKeys(); if (selectedChannels != selectedKeys.size()) { // Selector.select() returned because of a call to Selector.wakeup() // so do synchronization. } // Continue with handling selected channels.
wäre es richtig erkennen Wakeup-Call?
Hintergrundinformation:
ich einen Server zu schreiben, die die meiste Zeit nur Pakete und speichert sie in einer Datei empfängt. Sehr selten muss die Anwendung ein spezielles Paket senden. Hierzu initiiert er eine Verbindung (von einem anderen Thread) an den Server-Socket:
SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); channel.connect(new InetSocketAddress(InetAddress.getLocalHost(), PORT)); selector.wakeup(); SelectionKey key = channel.register(selector, SelectionKey.OP_CONNECT);
Das Problem ist, dass SelectableChannel.register() blockieren könnte, wenn der Haupt-Thread bereits in Selector.select ist(). Um dies zu verhindern, rufe ich Selector.wakeup() auf, wodurch der Haupt-Thread vorzeitig von select() zurückkehrt. Um sicherzustellen, dass der andere Thread die Möglichkeit hat, den Register-Aufruf abzuschließen, müsste ich den Haupt-Thread synchronisieren, aber ich würde es tun müssen, nachdem alle von select() zurückkehren. Wenn ich feststellen könnte, ob es aufgrund eines wakeup() -Aufrufs von select() zurückgegeben wurde, könnte ich es nur für diesen Fall optimieren.
in der Theorie also das Top-Code-Snippet sollte funktionieren, aber ich habe mich gefragt, ob es nur so tun würde, weil es auf einem unbestimmtes Verhalten beruht?
Danke für Hinweise.
Was ist Ihre Motivation für die Vermeidung von Sperren? Machen Sie sich Sorgen über die Ausführungszeit oder rufen Sie an vielen Stellen select() auf und möchten Code-Duplikation vermeiden? –
Ich mache mir Sorgen über die Ausführungszeit, obwohl dies ein strittiger Punkt sein könnte, da select() und register() bereits auf den registrierten Schlüsseln synchronisieren. – BugSlayer
Einverstanden, sich darüber Gedanken zu machen, ist ein klassisches Beispiel für vorzeitige Optimierung. Wenn Sie nicht wirklich über Toleranzen von einer Mikrosekunde sprechen, werden Sie keine Verlangsamung bemerken. Ich werde eine Antwort mit Sperren werfen. –