I have a class, called counter. It looks 开发者_开发知识库like this:
public class Counter {
private int count;
public Counter() {
count = 1;
}
public int getCount(){
return count;
}
public void incrementCount(){
count++;
}
I want to share a single instance of this between every user of a tomcat application. So user 1 and user 2 would both see getCount() as the same value. Assume for this that there is a technical reason why I can't store and read from a database.
Any advice?
Thanks.
Just create one and store it in the application scope during server's startup.
@WebListener
public class Config implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("counter", new Counter());
}
// ...
}
This way it's available in every servlet as follows:
Counter counter = (Counter) getServletContext().getAttribute("counter");
// ...
And in every JSP as follows:
<p>The count is ${counter.count}</p>
See also:
- What's the difference between static methods and applying singleton pattern?
- Synchronized singleton pattern
Unrelated to the concrete problem, your counter is not threadsafe. I'd suggest to use AtomicInteger
instead of int
.
public class Counter {
private AtomicInteger count = new AtomicInteger();
public Counter() {
count.incrementAndGet();
}
public int getCount(){
return count.get();
}
public void incrementCount(){
count.incrementAndGet();
}
}
You can use Singleton pattern.
Try this:
public class Counter {
private int count;
private static Counter instance = null;
private static Object lockObj = new Object();
private Counter() {
count = 1;
}
public static Counter Instance(){
synchronized(lockObj){
if(instance == null){
instance = new Counter();
}
}
return instance;
}
public int getCount(){
return count;
}
public void incrementCount(){
count++;
}
}
and somewhere in your code you can use: Counter.Instance().getCount()
A singleton that works in Java with proper locking:
public class Counter {
private AtomicInteger counter = new AtomicInteger(0);
private static class Initilizer {
private static Counter instance = new Counter();
}
private Counter() {}
public Counter instance() { return Initilizer.instance; }
public int getCount() { return counter.get() }
public void increment() { counter.incrementAndGet(); }
}
get the count: Counter.instance().getCount()
increment: Counter.instance().increment()
The difference between the 2 answers is the synchronization and singleton initialization which is optimized for java
精彩评论