I'm making a game in Java using Netbeans() and I want a Boolean variable takes the value of true when it is taken an item "X", the item "X" represents a character's ability which lasts "N" miliSeconds, what is the best way to do that after "N" miliSeconds the variable returns the value from false?
Now, not sure if it is my place to say, but I have a recommendation and an answer.
I would recommend building a skills/ability library. Use that to track cool downs, casting times etc. It would be more efficient overall.
As for the answer, check to see if the current time minus the time the ability was started is over 1000, then set the variable. Have this be used in a looped system such as a thread.
new Thread(new Runnable() {
try {
Thread.sleep(1000); //1 second
catch (InterruptedException annoyingCheckedException) {}
x = "foo";
}
You can start a new thread which waits a second (or however long you want it to wait) and then changes x.
The try-catch is because when sleeping, Java forces you to catch an InterruptedException which will be thrown if the thread is interrupted. In this case, you are never going to interrupt the thread so you don't need to worry about it.
Related
I am playing around with multithreading and came across an inconsistency when running a small snippet of code. The following code should print out 123123... but what I'm getting is
class RunnableDemo implements Runnable {
private String message;
RunnableDemo(String m) {
message = m;
}
public void run() {
try {
for (int i = 0; i < message.length(); i++) {
System.out.print(message.charAt(i));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
new Thread(new RunnableDemo("1111111")).start();
new Thread(new RunnableDemo("2222222")).start();
new Thread(new RunnableDemo("3333333")).start();
}
}
Output: 123231231132123231321
Output: 123213123123213213213
Output: 123231213213231231213
What I don't get is that it run correctly the first pass through (prints '123') but then the second pass through it prints '231'. If the thread is printing a char, sleeping 1 second, then repeating. Shouldn't the pattern 123123... be consistent each time I run the code or at least follow the pattern of the first 3 chars?
The following code should print out 123123
Not necessarily. You should basically never rely on threads with no synchronization between them happening to wake up and execute in any particular order.
Let's take the very first character output: there's no guarantee that that will be 1. Yes, you're starting the thread printing 1 first, but that doesn't mean that's the first thread that will actually start executing run first - or even if it does, that doesn't mean that's the first thread that will get as far as the System.out.print call.
Given the fairly long sleep, I would expect (but ideally not rely on) the output being a sequence of 7 "chunks", where each "chunk" consists of the characters "123" in some permutation. But if you've got three threads which all go to sleep for a second at "roughly" the same time, you shouldn't expect them to necessarily wake up in the order 1, 2, 3 - and again, even if they do, one of them may pre-empt another within the loop body.
On a really, really slow machine, even that expectation would be invalid - imagine it takes a random amount of time between 0 and 20 seconds to call charAt - unlikely, but it's a feasible thought experiment. At that point, one of the threads could race ahead and finish its output before another of the threads managed to print anything.
Threads are designed to be independent - if you want them to work in a coordinated fashion, you have to specify that coordination yourself. There are plenty of tools for the job, but don't expect it to happen magically.
You can't predict what piece of program CPU runs at a time. While running some process the CPU converts the process into small pieces of work. As multiple processes are running at a time. CPU has to schedule according to scheduling algorithm implemented. So, in short, you cannot predict what CPU does next unless you programmatically synchronize the pieces of code.
Say, for example, I want to run the following program
double x = 15.6
System.out.println(x);
But I wanted to repeat the program until a certain time has elapsed, such as the following:
do{
double x = 15.6
System.out.println(x);
}while (current time is earlier than 12.00pm)
Even though the example is completely hypothetical, how would I make that do while loop so that the program would keep running over and over again until a certain time, say 3pm, or9.30pm.
If this is not possible, is there any way I can simulate this, by running the program every so many seconds, until that time has been reached?
a) You usually don't need the code to actually run until a time has come - you wouldn't have any control over the amount of times the code executed this way. Regular code has to sleep sometimes, to give control to OS and other processes so that they don't clog the system with 100% CPU load. As such, actually running the code constantly is a wrong approach to 99% of the possible problems related to timings. Please describe the exact problem you want to solve using this code.
b) For those 99% of problems, use a Timer instance. Simple as that. https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html - schedule the task to run e.g. 1000 times a second, and check the time in each event, terminating the Timer instance when the time threshold has been exceeded.
For example, this code above will give you continuous execution of Do something part, every 1 second, until 16.11.2014 20:00 GMT. By changing delayMs you can easily achieve higher/lower time granularity. If you expect your code to be run more often than 1000/sec, you should probably use JNI anyway, since Java timers/clocks are known to have <10ms granularity on some (older) platforms, see How can I measure time with microsecond precision in Java? etc.
Timer timer = new Timer();
int delayMs = 1000; // check time every one second
long timeToStop;
try {
timeToStop = new SimpleDateFormat( "DD.MM.YYYY HH:mm" ).parse( "16.11.2014 20:00" ).getTime(); // GMT time, needs to be offset by TZ
} catch (ParseException ex) {
throw new RuntimeException( ex );
}
timer.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
if ( System.currentTimeMillis() < timeToStop ) {
System.out.println( "Do something every " + delayMs + " milliseconds" );
} else {
timer.cancel();
}
}
}, 0, delayMs );
or you can use e.g. ExecutorService service = Executors.newSingleThreadExecutor(); etc. - but it's virtually impossible to give you a good way to solve your problem without explicitly knowing what the problem is.
Something like this
//get a Date object for the time to stop, then get milliseconds
long timeToStop = new SimpleDateFormat("DD:MM:HH:mm").parse("16:11:12:00").getTime();
//get milliseconds now, and compare to milliseconds from before
do {
//do stuff
} while(System.currentTimeMillis() < timeToStop)
I am currently trying to run multiple methods of the same method at the same time. Right now it is only doing one at a time and then sleeping once it loops through all of them. I need it to do all the values in the array at the same time via the method. Here is my current code:
public static void checkTimer(TS3Api api) {
for (String keys : admins) {
//What I need: Check Groups for all values in string AT THE SAME TIME
checkGroup(api, keys);
}
try {
//Sleep for 10 second
Thread.sleep(10000);
} catch (InterruptedException e) {
// Do nothing
}
}
Thread.sleep(10000) causes the current thread to sleep for 10 seconds. This would be the primary thread. You have not split off any threads from the primary one, so this is working as you wrote it.
Take a look through the Java documentation http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
There are some examples of splitting off threads. This should get you on your way to a solution.
In Java 8 you can write something like:
admins.parallelStream().forEach(keys -> checkGroup(api, keys));
The number of items it will do in parallel are system dependent, however. In any case, it is unlikely you can do all of them in parallel unless your system has at least as many processors as there are items in admins, no matter what approach you take.
I am doing a past exam paper of Java, I am confused about one question listed below:
What would happen when a thread executes the following statement in its run() method? (Choose all that apply.)
sleep(500);
A. It is going to stop execution, and start executing exactly 500 milliseconds later.
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
C. It is going to result in a compiler error because you cannot call the sleep(…) method inside the run() method.
D. It is going to result in a compiler error because the sleep(…) method does not take any argument.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me? Many thanks.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me?
Yes, depending on your application, you certainly might get 500ms of sleep time and not a nanosecond more.
However, the reason why B is the better answer is that there are no guarantees about when any thread will be run again. You could have an application with a large number of CPU bound threads. Even though the slept thread is now able to be run, it might not get any cycles for a significant period of time. The precise sleep time also depends highly on the particulars of the OS thread scheduler and clock accuracy. Your application also may also have to compete with other applications on the same system which may delay its continued execution.
For example, this following program on my extremely fast 8xi7 CPU Macbook Pro shows a max-sleep of 604ms:
public class MaxSleep {
public static void main(String[] args) throws Exception {
final AtomicLong maxSleep = new AtomicLong(0);
ExecutorService threadPool = Executors.newCachedThreadPool();
// fork 1000 threads
for (int i = 0; i < 1000; i++) {
threadPool.submit(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
long total = 0;
// spin doing something that eats CPU
for (int j = 0; j < 10000000; j++) {
total += j;
}
// this IO is the real time sink though
System.out.println("total = " + total);
try {
long before = System.currentTimeMillis();
Thread.sleep(500);
long diff = System.currentTimeMillis() - before;
// update the max value
while (true) {
long max = maxSleep.get();
if (diff <= max) {
break;
}
if (maxSleep.compareAndSet(max, diff)) {
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out.println("max sleep ms = " + maxSleep);
}
}
JVM cannot guarantee exactly 500 ms but it will start on or after ~500 ms as it will need to start its 'engine' back considering no other threads are blocking any resources which may delay a bit.
Read: Inside the Hotspot VM: Clocks, Timers and Scheduling Events
Edit: As Gray pointed out in the comment - the scheduling with other threads also a factor, swapping from one to another may cost some time.
According to Javadoc:-
Sleep()
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors.
So it may be ~500ms
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
Looks more prominent.
As you know that there are two very closely-related states in Thread : Running and Runnable.
Running : means currently executing thread. Its execution is currently going on.
Runnable : means thread is ready to get processed or executed. But is waiting to be picked up by Thread Schedular. Now this thread schedular, as per its own wish/defined algorithm depending upon the JVM(for example, slicing algorithm) will pick up one of the available/Runnable threads to process them.
So whenever you call sleep method, it only guarantees that the execution of the code by the thread which it ran on, is paused for the specified milliseconds in the argument(e.g. 300ms in threadRef.sleep(300);). As soon as the time defined goes by, it comes back to Runnable state(means back to Available State to be picked up by Thread Schedular).
Therefore, there is no guarantee that your remaining code will start getting executed immediately after sleep method completion.
These sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Option B: Not earlier than 500 is more correct.
You cannot select A and B as they are opposite to each other, the main difference: exactly 500 milliseconds later and not earlier than 500 milliseconds later
first mean exactly what it means (500 milliseconds only), second means that it can sleep 501 or 502 or even 50000000000000
next question - why B is true, it is not so simply question, you need to understand what is the different between hard-realtime and soft-realtime, and explaining of all reasons is quite offtopic, so simply answer - because of many technical reasons java cannot guarantee hard real time execution of your code, this is why it stated that sleep will finish not earlier than ...
you can read about thread scheduling, priorities, garbage collection, preemptive multitasking - all these are related to this
I am doing a POC with the rabbitMQ and writing a program to add two numbers and getting the response.
The code that we wrote to retrieve the value from the queue is running infinite time( in a while loop) and a line( inside the while loop) waits for some data to be retrieved from the queue; until it gets something from queue it will not go for the next round of the while loop.
Means we are getting the value inside an infinite loop.
And I want to use this value for my next processing.
while (true)
{
QueueingConsumer.Delivery delivery1;
try
{
delivery = consumer.nextDelivery();
//The above line waits until delivery get some value
String result1 = new String(delivery1.getBody());
System.out.println("Result received-"+ result1);
}
catch (InterruptedException ie)
{
continue;
}
} // end while
Problem is that I am not able to return the value from the while loop( I want to run it infinite time).
How can I do that so the loop will continue and I will get the processed data outside loop too?
If 'processing the result' is an operation that completes quickly, then just do it inline, e.g. by calling a separate function that does the actual processing:
void mainLoop()
{
while (true)
{
QueueingConsumer.Delivery delivery1;
try
{
delivery = consumer.nextDelivery();
//The above line waits until delivery get some value
String result1 = new String(delivery1.getBody());
System.out.println("Result received-"+ result1);
processResult(result1);
}
catch (InterruptedException ie)
{
continue;
}
} // end while
}
void processResult(String result)
{
// Do whatever needs to be done with 'result'
}
If you need processing to happen concurrently with the loop, then you will need to work with multiple threads and the problem gets a bit more complicated.
What do you mean by that exactly?
If you want to stay in the same thread, just call a function (work on the one message received and than read the next).
If you need concurrency (always read, regardless whether you a re processing a message or not) use a producer/ consumer pattern.
Create one thread that
reads from the mq
posts into a (thread-safe) collection
signals that
goes back to read from the mq
Create at least one mor thread that
waits for the signal
reads (and removes) message from the (thread-safe) collection
process the message
goes back to wait for the signal
hth
Mario
Make your return value having more visibility.
So, you'll gain access to it's value
It sounds like you're referring to the yield feature which allows your function to return multiple values. As far as I know this is not supported out-of-the-box in Java but there are some projects available that implement this feature.