开发者

Sharing a class instance between all users with Tomcat

开发者 https://www.devze.com 2023-02-25 03:01 出处:网络
I have a class, called counter. It looks 开发者_开发知识库like this: public class Counter { private int count;

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

0

精彩评论

暂无评论...
验证码 换一张
取 消