2015-04-26 4 views
0

Сервлеты не являются потокобезопасными, состояние может быть потеряно между вызовами методов различными запросами.Сервлеты подходят для композитных операций?

Но могу ли я сохранить состояние между собственными методами сервлета во время запросить безопасное выполнение сложных операций?

Как это:

public class MyServlet extends HttpServletRequest { 

    private String var; 

    void addH() { 
     var += "h"; 
    } 

    void addI() { 
     var += "i"; 
    } 

    void doGet(...) { 
     addH(); 
     addI(); 
     // var = "hi"? 
    } 
} 

Будет ли var содержать правильное значение в этом случае даже при одновременных запросов? Другими словами, работает ли он как фанатичный боб в EJB?

+0

попробовать! сделать два запроса и посмотреть, что произойдет – daniel

+0

@ daniel, это заметно только при использовании параллельных запросов, не знаю, как :( – WildDev

ответ

1

Нет, вы не можете. Как вы сказали, сервлеты не являются потокобезопасными. Там нет защищенного «пространства», в котором содержится запрос. Таким образом, несколько потоков (и, следовательно, запросов) могут одновременно удалять var. Если вы хотите такое защищенное «пространство», вам нужно либо синхронизировать doGet() (что, конечно же, приведет к уничтожению параллелизма), либо что-то вроде использования ThreadLocal, так что каждый поток (и, следовательно, запрос) будет иметь свою собственную отдельную копию состояния экземпляра.

Если вы не нуждаетесь в состоянии сохраняться вне запросов, вы можете просто создать государство в doGet() и передать его другим методам:

void doGet(...) { 
    StringBuilder var = new StringBuilder(); 
    addH(var); 
    addI(var); 
    resp.write(var.toString()); 
} 

void addH(StringBuilder var) { 
    var.append('h'); 
} 

void addI(StringBuilder var) { 
    ver.append('i'); 
} 
1
public class MyServlet extends HttpServletRequest { 

    private String var = ""; 

    void addH() { 
     var += "h"; 
    } 

    void addI(long dontAnswerBefore) { 
     while(System.currentTimeMillis() < dontAnswerBefore) { 
      // Do nothing 
     } 
     var += "i"; 
    } 

    void doGet(...) { 
     long now = System.currentTimeMillis(); 
     addH(); 
     addI(now + 10_000); 
     resp.write(var); 
    } 
} 

Это должно дать вам 10 секунд, чтобы сделать два Запроса в пределах двух вкладок или двух разных браузеров.

Смежные вопросы