Sincronização em tópicos para Java
-
05-07-2019 - |
Pergunta
Eu tenho um servidor web cultivado em casa em meu aplicativo. Este servidor web gera um novo segmento para cada solicitação que vem no soquete para ser aceito. Eu quero que o servidor web que esperar até um ponto específico é atingido no segmento em que acabou de criar.
Já passei por muitos posts sobre este site e exemplos na web, mas não pode ter o servidor web para prosseguir depois de eu dizer o segmento para esperar. Um exemplo de código básico seria ótimo.
É a palavra-chave sincronizada a maneira correta de fazer isso? Se sim, como isso pode ser alcançado? exemplos de código estão abaixo do meu aplicativo:
Web Server
while (true) {
//block here until a connection request is made
socket = server_socket.accept();
try {
//create a new HTTPRequest object for every file request
HttpRequest request = new HttpRequest(socket, this);
//create a new thread for each request
Thread thread = new Thread(request);
//run the thread and have it return after complete
thread.run();
///////////////////////////////
wait here until notifed to proceed
///////////////////////////////
} catch (Exception e) {
e.printStackTrace(logFile);
}
}
Código de rosca
public void run() {
//code here
//notify web server to continue here
}
Update - código final é como abaixo. O HttpRequest
não apenas chamar resumeListener.resume()
sempre que eu enviar um cabeçalho de resposta (é claro que também adicionando a interface como uma classe separada eo método addResumeListener(ResumeListener r1)
em HttpRequest
):
parte Web Server
// server infinite loop
while (true) {
//block here until a connection request is made
socket = server_socket.accept();
try {
final Object locker = new Object();
//create a new HTTPRequest object for every file request
HttpRequest request = new HttpRequest(socket, this);
request.addResumeListener(new ResumeListener() {
public void resume() {
//get control of the lock and release the server
synchronized(locker) {
locker.notify();
}
}
});
synchronized(locker) {
//create a new thread for each request
Thread thread = new Thread(request);
//run the thread and have it return after complete
thread.start();
//tell this thread to wait until HttpRequest releases
//the server
locker.wait();
}
} catch (Exception e) {
e.printStackTrace(Session.logFile);
}
}
Solução
Primeiro de tudo, eu ecoar o sentimento dos outros que re-inventar a roda aqui provavelmente levará a uma variedade de questões para você. No entanto, se você quiser ir por este de qualquer maneira estrada que você está tentando fazer não é difícil. Você já experimentou com Jetty?
Talvez algo como isto:
public class MyWebServer {
public void foo() throws IOException {
while (true) {
//block here until a connection request is made
ServerSocket socket = new ServerSocket();
try {
final Object locker = new Object();
//create a new HTTPRequest object for every file request
MyRequest request = new MyRequest(socket);
request.addResumeListener(new ResumeListener() {
public void resume() {
locker.notify();
}
});
synchronized(locker){
//create a new thread for each request
Thread thread = new Thread(request);
//start() the thread - not run()
thread.start();
//this thread will block until the MyRequest run method calls resume
locker.wait();
}
} catch (Exception e) {
}
}
}
}
public interface ResumeListener {
public void resume();
}
public class MyRequest implements Runnable{
private ResumeListener resumeListener;
public MyRequest(ServerSocket socket) {
}
public void run() {
// do something
resumeListener.resume(); //notify server to continue accepting next request
}
public void addResumeListener(ResumeListener rl) {
this.resumeListener = rl;
}
}
Outras dicas
Você pode usar java.util.concurrent .CountDownLatch com uma contagem de 1 para isso. Organizar para uma instância que seja criado e compartilhado pelo segmento pai e criança (por exemplo, criar-lo no construtor do HttpRequest
, e tê-lo recuperáveis ??por uma função de membro). O servidor seguida, chama await()
sobre ele, e os hits de rosca countDown()
quando estiver pronto para liberar seu pai.
Você provavelmente precisará usar um Java Condição . De docs:
Condições (também conhecidos como condição filas ou variáveis ??de condição) fornecer um meio para um segmento para suspender execução (a "espera") até ser notificado por outro segmento que algum estado condição pode agora ser verdade.
Executar sob um depurador e definir um ponto de interrupção?
Se inviável, em seguida, ler uma linha de System.in?