Java NIO - Selektor
Seperti yang kita ketahui bahwa Java NIO mendukung banyak transaksi dari dan ke saluran dan buffer. Jadi untuk memeriksa satu atau lebih Saluran NIO, dan menentukan saluran mana yang siap untuk transaksi data yaitu membaca atau menulis Java NIO menyediakan Selector.
Dengan Selector kita dapat membuat utas untuk mengetahui saluran mana yang siap untuk menulis dan membaca data dan dapat menangani saluran tertentu itu.
Kita bisa mendapatkan contoh pemilih dengan memanggil metode statisnya open()Setelah selektor terbuka, kita harus mendaftarkan saluran mode non pemblokiran dengannya yang mengembalikan instance dari SelectionKey.
SelectionKey pada dasarnya adalah kumpulan operasi yang dapat dilakukan dengan saluran atau kita dapat mengatakan bahwa kita dapat mengetahui status saluran dengan bantuan tombol pilihan.
Operasi utama atau status saluran yang diwakili oleh tombol pilihan adalah -
SelectionKey.OP_CONNECT - Channel yang siap terkoneksi ke server.
SelectionKey.OP_ACCEPT - Saluran yang siap menerima koneksi masuk.
SelectionKey.OP_READ - Channel yang siap membaca data.
SelectionKey.OP_WRITE - Channel yang siap untuk menulis data.
Kunci pilihan yang diperoleh setelah pendaftaran memiliki beberapa metode penting seperti yang disebutkan di bawah ini -
attach() - Metode ini digunakan untuk melampirkan objek dengan kunci. Tujuan utama melampirkan objek ke saluran adalah untuk mengenali saluran yang sama.
attachment() - Metode ini digunakan untuk mempertahankan objek yang terpasang dari saluran.
channel() - Metode ini digunakan untuk mendapatkan saluran di mana kunci tertentu dibuat.
selector() - Metode ini digunakan untuk mendapatkan selektor yang darinya kunci tertentu dibuat.
isValid() - Metode ini mengembalikan apakah kuncinya valid atau tidak.
isReadable() - Metode ini menyatakan bahwa saluran kunci cuaca siap untuk dibaca atau tidak.
isWritable() - Metode ini menyatakan bahwa saluran kunci cuaca siap untuk ditulis atau tidak.
isAcceptable() - Metode ini menyatakan bahwa saluran kunci cuaca siap untuk menerima koneksi masuk atau tidak.
isConnectable() - Metode ini menguji apakah saluran kunci ini telah selesai, atau gagal menyelesaikan, operasi koneksi soketnya.
isAcceptable() - Metode ini menguji apakah saluran kunci ini siap menerima koneksi soket baru.
interestOps() - Metode ini mengambil set minat kunci ini.
readyOps() - Metode ini mengambil set siap yang merupakan rangkaian operasi yang siap untuk saluran.
Kita dapat memilih saluran dari selektor dengan memanggil metode statisnya select()Metode. Pilih selektor kelebihan beban karena -
select() - Metode ini memblokir utas saat ini hingga setidaknya satu saluran siap untuk acara yang didaftarkan.
select(long timeout) - Metode ini melakukan hal yang sama seperti select () kecuali itu memblokir utas selama maksimum milidetik batas waktu (parameter).
selectNow() - Metode ini tidak memblokir sama sekali. Metode ini segera kembali dengan saluran apa pun yang siap.
Juga untuk meninggalkan utas yang diblokir yang memanggil metode pilih,wakeup() metode bisa dipanggil dari contoh selektor setelah itu utas menunggu di dalam select () kemudian akan segera kembali.
Terakhir, kita dapat menutup selektor dengan memanggil close() metode yang juga membatalkan semua instance SelectionKey yang terdaftar dengan Selector ini bersama dengan menutup selector.
Contoh
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class SelectorDemo {
public static void main(String[] args) throws IOException {
String demo_text = "This is a demo String";
Selector selector = Selector.open();
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.bind(new InetSocketAddress("localhost", 5454));
serverSocket.configureBlocking(false);
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer buffer = ByteBuffer.allocate(256);
while (true) {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
int interestOps = key.interestOps();
System.out.println(interestOps);
if (key.isAcceptable()) {
SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
client.read(buffer);
if (new String(buffer.array()).trim().equals(demo_text)) {
client.close();
System.out.println("Not accepting client messages anymore");
}
buffer.flip();
client.write(buffer);
buffer.clear();
}
iter.remove();
}
}
}
}