I've got a problem which is kinda obvious, though I'm not sure how to solve it.
I've got 2 classes, 1 of which is Interceptor.
#Stateless
#Interceptors(AutoId.class)
public class TestClass {
private static final Logger LOG = Logger.getLogger(RepositoryBean.class.getName());
public void executeUpdate(){
int k=0;
for (int i = 0; i < 1000000; i++) {
for (int j = 0; j < 100000; j++) {
for (int r = 0; r < 1000000; r++) {
k = 1;
}
}
}
getLogger().log(Level.INFO, "Current time some time ago was "+AutoId.MyTime/1000);
}
private Logger getLogger() {
return Logger.getLogger(getClass().getCanonicalName());
}}
and here is Interceptor class:
public class AutoId {
public static Long MyTime;
#AroundInvoke
public Object addLog(InvocationContext context) throws Exception {
MyTime= System.currentTimeMillis();
return context.proceed();
}
}
an obvious problem is that if I run this application (when it's deployed on a glassfish server) and then in a couple of seconds I run another copy of it, it is going to rewrite MyTime variable with new time and, as a result, both programs will print same time.
One of the obvious solutions is to make a variable inside executeUpdate which will save the value of MyTime, BUT this is not good for the real project I'm working on.
I was told that I might want to do something with ContextResolver and #Context.
Any thoughs on how do I solve this?
Thanks.
EDIT
I found one solution, though I don't think it is the best
public class AutoId {
private static Long[] MyTime = new Long[1000];
#AroundInvoke
public Object addLog(InvocationContext context) throws Exception {
MyTime[(int)Thread.currentThread().getId()]= System.currentTimeMillis();
return context.proceed();
}
public static Long MyTime(){
return MyTime[(int)Thread.currentThread().getId()];
}
}
naming array the same way as procedure allows to minimize code changes in main class only by adding () after AutoId.MyTime -> AutoId.MyTime()
That's still not the best Idea, though it doesn't cause rewriting of variable anymore.
EDIT2 please don't really mind all the code in executeUpdate() procedure. It is just written in a way it takes some tome to finish working, so that I can execute 1 more copy of it and print out AutoId.MyTime. The value of this variable is the only thing that matters.
Also it's qute obvious that if I wasn't using Interceptor and just created an AutoId variable within class to call it before any other procedure (that's what interceptors for) that error wouldn't appear since every copy of program will have its own id easily - that's not option though. Interceptors are required for autorisation here before executing any procedure. Hope that explains everything I haven't told before :)
You could use #Produces for logger creation and use then #Inject to inject your logger in your class and interceptor. This way you should log different times.
Related
Could you help me with one thing? Imagine I have a simple RESTful microserver with one GET method which simply responds with a random String.
I assemble all the strings in a ConcurrentHashSet<String> that holds all answers.
There is a sloppy implementation below, the main thing is that the Set<String> is a fail-safe and can be modified simultaneously.
#RestController
public class Controller {
private final StringService stringService;
private final CacheService cacheService;
public Controller(final StringService stringService, final CacheService cacheService) {
this.stringService = stringService;
this.cacheService = cacheService;
}
#GetMapping
public String get() {
final String str = stringService.random();
cacheService.add(str);
return str;
}
}
public class CacheService {
private final Set<String> set = ConcurrentHashMap.newKeySet();
public void add(final String str) {
set.add(str);
}
}
While you are reading this line my endpint is being used by 1 billion people.
I want to shard the cache. Since my system is heavily loaded I can't hold all the strings on one server. I want to have 256 servers/instances and uniformly distribute my cache utilizing str.hashCode()%256 function to determine on each server/instance should a string be kept.
Could you tell me what should I do next?
Assume that currently, I have only running locally Spring Boot application.
You should check out Hazelcast, it is open source and has proved useful for me in a case where i wanted to share data among multiple instances of my application. The In-memory data grid provided by hazelcast might just be the thing you are looking for.
I agree with Vicky, this is what Hazelcast is made for. It's a single jar, a couple lines of code and instead of a HashMap, you have an IMap, which is an extension of HashMap, and you're good to go. All the distribution, sharding, concurrency, etc is done for you. Check out:
https://docs.hazelcast.org/docs/3.11.1/manual/html-single/index.html#map
Try follow codes.But,it is a bad way,you best use Map to cache your data in one instance.If you need to create distributed application,try distributed catche service like Redis.
class CacheService {
/**
* assume read operation is more frequently than write operation
*/
private final static List<Set<String>> sets = new CopyOnWriteArrayList<>();
static {
for (int i = 0; i < 256; i++) {
sets.add(ConcurrentHashMap.newKeySet());
}
}
public void add(final String str) {
int insertIndex = str.hashCode() % 256;
sets.get(insertIndex).add(str);
}
}
I am working with a priority queue in Java for the first time and I can't for the life of me understand what I am doing that is leading to the exception. I'm attempting to implement an ant colony type solution to the traveling salesman problem. The following is the only code being called for my AntColony class.
public AntColony(TSPInstance p) {
PriorityQueue<Ant> ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
for (int i = 0; i < size; i++) {
ants.offer(new Ant(p));
}
shortestTour = Integer.MAX_VALUE;
}
public void nextMove() {
ants.poll();
}
The code that I'm running afterwards just as a test is as follows (just in a main method).
AntColony a = new AntColony(p);
a.nextMove();
The a.nextMove() throws a NullPointerException at the ants.poll() part, but yet if I change the constructor to (for debugging purposes)
public AntColony(TSPInstance p) {
PriorityQueue<Ant> ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
for (int i = 0; i < size; i++) {
ants.offer(new Ant(p));
}
ants.poll(); //ADDED THIS
shortestTour = Integer.MAX_VALUE;
}
and then just do
AntColony a = new AntColony(p);
I don't get an exception. I'm struggling to understand how I'm getting an exception from ants.poll(), but yet when I call it from the constructor everything works. Any help with this would be appreciated. There's a lot of code for various things in this project, so I didn't think uploading it all would help anybody so let me know if there's something I should include, but I don't see how the problem could lie outside these two bits of code.
Added: Actual exception
Exception in thread "main" java.lang.NullPointerException
at data_structures.AntColony.nextMove(AntColony.java:25) (the ants.poll() part)
at algorithms.ACTest.main(ACTest.java:6) The a.nextMove() part
The ants variable in your AntColony constructor is a local variable. So when you exit the constructor, it no longer exists. Apparently the ants variable that your nextMove method is calling, is a class member.
You need to change your constructor to have:
// initialize the class member, not a local instance.
ants = new PriorityQueue<Ant>(new AntComparator());
You can just remove the PriorityQueue declaration in your AntColony constructor.
public AntColony(TSPInstance p) {
ants = new PriorityQueue<Ant>(new AntComparator());
size = p.getDimension();
...
}
UPDATE: The cause for your NullPointerException is that you are not initializing your ants property in your constructor but you are creating a new local ants instead. So the ants object in nextMove method has the same value as you provided in your class level declaration, which it's probably null.
In Java I have a String object that has the text that I wish to be matched and executed by JBehave as a step. How can this be done? Can it be done?
What I am really trying to do is to have a wrapper JBehave step that instruments another arbitrary JBehave step. It does a few things before and after calling on the "inner" step.
So lets say that I already have the following
When I say Hello World
and
#When("I say $text")
public void iSay(final String text)
{
System.out.println(text);
}
I want to be able to do the following :
When I repeat 4 times I say Hello World
it will call :
#When("I repeat $count times $subStepString")
public void repeat(final int repeatCount, final String subStepString)
{
// prep code here
for (int i = 0; i < repeatCount; i++)
{
howDoIdoThisBitHere(subStepString);
}
// post process code here
}
The part that says howDoIdoThisBitHere(...) should end up having JBehave match the value of subStepString as if it was encountered in the case above. This way I can use this method to call other arbitrary things.
I'm not sure this is a great idea since the step classes shouldn't have any dependency on the core configuration (StepMatchers, Runners etc.), but is this solution kind of what you're looking for?
#When("I repeat $count times $subStepString")
public void repeat(final int repeatCount, final String subStepString)
{
// prep code here
for (int i = 0; i < repeatCount; i++)
{
StoryParser sp = configuration().storyParser();
Story s = sp.parseStory(subStepString);
StoryRunner e = configuredEmbedder().storyRunner();
e.run(configuration(), configuredEmbedder().candidateSteps(), s);
}
}
I am about to cleanup/format over 700 Java files in my work using Eclipse's format and cleanup operations. My bosses are worried that all of this cleanup/formatting may cause changes in runtime behavior.
As far as I am aware the only cleanup/format preference that may change runtime behavior is "Clean Up/Code Organizing/Members/Sort Members/Sort all members" and Eclipse warns you about this.
So my question is aside from the preference mentioned above are all other Eclipse cleanup and format preferences safe? Or has anyone ever come across a situation where performing cleanup/format has changed their program's runtime behavior?
Thanks for your time.
Although unlikely it is possible that changing the order of a field declaration or initializer could cause changes at runtime. Take this example:
public class MyClass {
private static int I;
private static int J = I + 1;
static {
I = 2;
}
}
If you reorder the declarations like this the value of J will end up getting initialized to 3 instead of 1.
public class MyClass {
private static int I;
static {
I = 2;
}
private static int J = I + 1;
}
Does anyone know how can I create a new Performance Counter (perfmon tool) in Java?
For example: a new performance counter for monitoring the number / duration of user actions.
I created such performance counters in C# and it was quite easy, however I couldn’t find anything helpful for creating it in Java…
If you want to develop your performance counter independently from the main code, you should look at aspect programming (AspectJ, Javassist).
You'll can plug your performance counter on the method(s) you want without modifying the main code.
Java does not immediately work with perfmon (but you should see DTrace under Solaris).
Please see this question for suggestions: Java app performance counters viewed in Perfmon
Not sure what you are expecting this tool to do but I would create some data structures to record these times and counts like
class UserActionStats {
int count;
long durationMS;
long start = 0;
public void startAction() {
start = System.currentTimeMillis();
}
public void endAction() {
durationMS += System.currentTimeMillis() - start;
count++;
}
}
A collection for these could look like
private static final Map<String, UserActionStats> map =
new HashMap<String, UserActionStats>();
public static UserActionStats forUser(String userName) {
synchronized(map) {
UserActionStats uas = map.get(userName);
if (uas == null)
map.put(userName, uas = new UserActionStats());
return uas;
}
}