I have a while function. When it is true I want to proceed it only every 1 second. I can't use Thread.sleep(), because I am making Minecraft plugin and it will stop all processes on the server. Is there another way how to do it?
Thanks for your reply.
What you are looking for is the Bukkit Scheduler. It is integrated into the default plugin API and can be used to solve your task as following:
int taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
#Override
public void run() {
// do stuff
}
}, delay, repeat);
Set the delay to 0 and the repeat to 20 (20 Ticks are 1 second).
Stop it by using:
Bukkit.getScheduler().cancelTask(taskID);
you can create a java.util.TimerTask
which can schedule your task after a specified time delay .
more details here : https://www.geeksforgeeks.org/java-util-timertask-class-java/
If you use Thread.sleep() in the main Thread you will block the main thread and for avoid this you need to create a separate thread pass to then the values you will need for process whatever you want in your thread, some snippet code for clarification:
public static boolean ENABLE_THREAD = true;
public static void main(String args[]){
InnerThread minecraftThread = (new ThreadStack()).new InnerThread();
minecraftThread.run();
}
public class InnerThread implements Runnable{
#Override
public void run() {
int counter=0;
while(ENABLE_THREAD){
try {
//YOUR CODE
System.out.println(counter);
Thread.sleep(1000);
counter++;
if(counter>10){
ENABLE_THREAD = false;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
You can use System.currentTimeMillis():
public static void main(String[] args) {
//The while(true) is to keep the next while loop running, otherwise, in
//this example, the condition System.currentTimeMillis()-past>=1000
//won't be true
//It can be changed according to the needs
long past = System.currentTimeMillis();
while(true)
while(System.currentTimeMillis()-past>=1000)
{
/*
*DO what you need to do
*/
past = System.currentTimeMillis();
}
}
This is the simplest solution I can think of. Please check if it works for you.
long start = new Date().getTime();
while(new Date().getTime() - start < 1000L)
{
//Do Something every 1sec
//you need to update the start value everytime
start = new Date().getTime();
}
Related
I have got the basics of how Timer and TimerTask work in Java. I have a situation where I need to spawn a task that will run periodically at fixed intervals to retrieve some data from database. And it needs to be terminated based on the value of the retrieved data (the data itself is being updated by other processes)
Here is what I came up with so far.
public class MyTimerTask extends TimerTask {
private int count = 0;
#Override
public void run() {
count++;
System.out.println(" Print a line" + new java.util.Date() + count);
}
public int getCount() {
return count;
}
}
And a class with a main method like so. For now I have trivially used a 15 second sleep to control how long the timerTask runs.
public class ClassWithMain {
public static void main(String[] args) {
System.out.println("Main started at " + new java.util.Date());
MyTimerTask timerTask = new MyTimerTask();
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(timerTask, 0, 5*10*100);
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main done"+ new java.util.Date());
}
The MyTimerTask class will become more complex with the database service calls and so on.
What I want to be able to do is, in the main class, interrogate a value returned by timerTask to dictate when to invoke timer.cancel() and terminate the process. Right now if I try to use the count property of MyTimerTask it doesn't work. So when I tried adding these lines in ClassWithMain
if (timerTask.getCount() == 5){
timer.cancel();
}
it didn't stop the process.
So I'd like any direction on how I might be able to accomplish what I'm trying to do.
private volatile int count = 0; It is better to use 'volatile'.
try this in ClassWithMain:
for(;;) {
if (timerTask.getCount() == 5) {
timer.cancel();
break;
} else{
Thread.yield();
}
}
I am trying to do something in Java and I need something to wait / delay for an amount of seconds in a while loop.
while (true) {
if (i == 3) {
i = 0;
}
ceva[i].setSelected(true);
// I need to wait here
ceva[i].setSelected(false);
// I need to wait here
i++;
}
I want to build a step sequencer.
How do I make a delay in Java?
If you want to pause then use java.util.concurrent.TimeUnit:
TimeUnit.SECONDS.sleep(1);
To sleep for one second or
TimeUnit.MINUTES.sleep(1);
To sleep for a minute.
As this is a loop, this presents an inherent problem - drift. Every time you run code and then sleep you will be drifting a little bit from running, say, every second. If this is an issue then don't use sleep.
Further, sleep isn't very flexible when it comes to control.
For running a task every second or at a one second delay I would strongly recommend a ScheduledExecutorService and either scheduleAtFixedRate or scheduleWithFixedDelay.
For example, to run the method myTask every second (Java 8):
public static void main(String[] args) {
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(App::myTask, 0, 1, TimeUnit.SECONDS);
}
private static void myTask() {
System.out.println("Running");
}
And in Java 7:
public static void main(String[] args) {
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
myTask();
}
}, 0, 1, TimeUnit.SECONDS);
}
private static void myTask() {
System.out.println("Running");
}
Use Thread.sleep(1000);
1000 is the number of milliseconds that the program will pause.
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Use this:
public static void wait(int ms)
{
try
{
Thread.sleep(ms);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
and, then you can call this method anywhere like:
wait(1000);
You need to use the Thread.sleep() call.
More info here: http://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html
Use Thread.sleep(100);.
The unit of time is milliseconds
For example:
public class SleepMessages {
public static void main(String args[])
throws InterruptedException {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
for (int i = 0;
i < importantInfo.length;
i++) {
//Pause for 4 seconds
Thread.sleep(4000);
//Print a message
System.out.println(importantInfo[i]);
}
}
}
Using TimeUnit.SECONDS.sleep(1); or Thread.sleep(1000); Is acceptable way to do it. In both cases you have to catch InterruptedExceptionwhich makes your code Bulky.There is an Open Source java library called MgntUtils (written by me) that provides utility that already deals with InterruptedException inside. So your code would just include one line:
TimeUtils.sleepFor(1, TimeUnit.SECONDS);
See the javadoc here. You can access library from Maven Central or from Github. The article explaining about the library could be found here
I know this is a very old post but this may help someone:
You can create a method, so whenever you need to pause you can type pause(1000) or any other millisecond value:
public static void pause(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
System.err.format("IOException: %s%n", e);
}
}
This is inserted just above the public static void main(String[] args), inside the class. Then, to call on the method, type pause(ms) but replace ms with the number of milliseconds to pause. That way, you don't have to insert the entire try-catch statement whenever you want to pause.
There is also one more way to wait.
You can use LockSupport methods, e.g.:
LockSupport.parkNanos(1_000_000_000); // Disables current thread for scheduling at most for 1 second
Fortunately they don't throw any checked exception. But on the other hand according to the documentation there are more reasons for thread to be enabled:
Some other thread invokes unpark with the current thread as the target
Some other thread interrupts the current thread
I need a loop with delay (like a timer) but have problems with the end of it, this is my code:
while(true) {
if (someValue == 10) {
break;
}
//Wait two seconds. <-----
}
System.out.println("While Ended.");
This works fine, but need to be repeated every 2 seconds. I tried with Timer but the "While Ended." message is shown before of the timer end. How can i solve this problem?
I need that this process not freeze the thread. (like while loop).
Precision is not necessary.
You can put Thread.sleep in a while-loop to sleep for a number of seconds. This solution has problems, e.g. it blocks the thread, breaks on interrupts, etc.
Better is to use a ScheduledThreadPoolExecutor and use the schedule method to schedule the task to run every so many seconds. This is correct but you should have some knowledge of how multithreaded programs work or you'll make mistakes and create subtle bugs.
When you need something like a timer than you could use a timer:
import java.util.Timer;
import java.util.TimerTask;
public class TTimer extends TimerTask {
private static Timer timer;
#Override
public void run() {
System.out.println("timer");
}
public void stop() {
timer.cancel();
timer.purge();
this.cancel();
}
public TTimer( long interval) {
timer = new Timer(true);
timer.scheduleAtFixedRate(this, 0, interval);
}
public static void main(String[] args) {
TTimer t = new TTimer(2000);
while( true ) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
}
}
}
Place your code in the run() method, check your condition (somevalue == 10) and call the stop method to shut the timer down.
I have a requirement in which I have to check whether any file exists in the folder. If yes, then I need to process it one by one. With my basic knowledge I have arrived to a code structure which I have posted below.
I'm creating an infinite loop and checking whether the file exists in that folder. If yes, then I'm creating a thread and processing it, else it waits for a min and checks again.
class sample {
synchronized int getNoOfFiles() {
// get number of files in the folder
}
synchronized void openFile() {
// open one file
}
synchronized void getFileContents() {
// get the file content
}
synchronized void processFileContent() {
//performing some operation on file contents
}
synchronized void closeFile() {
//closing the file
}
synchronized void deleteFile() {
//delete the file
}
}
class Test {
public static void main(String args[]) {
int flag=0;
Sample obj = new Sample();
while(1) {
flag = obj.getNoOfFiles();
if(flag) {
for(i=0;i<flag;i++) {
MyThread1 t1 = new MyThread1() {
public void run() {
obj.openFile();
obj.getFileContents();
obj.processFileContent();
obj.closeFile();
obj.deleteFile();
}
};
t1.start();
}
}
else {
try {
Thread.sleep(60000);
}
}
}
}
}
Instead of doing this kind of thing yourself, I suggest you take a look at the Timer class, that can be used to do recurring tasks. Because messing around with threads manually can often result in weird bugs.
Even better would be ScheduledThreadPoolExecutor, but it might be a bit complicated if you've never used executors before. See Keppil's answer for how to do this.
The differences between the two are nicely summed up here: Java Timer vs ExecutorService?.
I would suggest using a ScheduledExecutorService:
ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(new Runnable() {
public void run()
{
obj.openFile();
obj.getFileContents();
obj.processFileContent();
obj.closeFile();
obj.deleteFile();
}
}, 0, 1, TimeUnit.MINUTES);
I'm working on making an interface for a robot. My Robot class has methods that include movement, stopping movement and reading sensor data. If at all possible, I'd like to have certain methods run under a given thread and certain other methods run under another. I'd like to be able to send the command to move to the robot object, have the thread executing it sleep duration milliseconds and then stop movement, but I'd like the stop() method able to be called and interrupt the thread executing the movement. Any help is greatly appreciated.
public class robotTest
{
public static void main(String[] args) throws InterruptedException
{
Robot robot = new Robot(); //Instantiate new Robot object
robot.forward(255, 100, Robot.DIRECTION_RIGHT, 10); //Last argument representing duration
Thread.sleep(5000); //Wait 5 seconds
robot.stop(); //Stop movement prematurely
}
}
I would suggest instantiating your Robot class with an ExecutorService that you can use for moving asynchronusly. Submit the movement request to your service and use the Future returned to 'stop' the move request.
class Robot{
final ExecutorService movingService = Executors.newSingleThreadExecutor();
private volatile Future<?> request; //you can use a Deque or a List for multiple requests
public void forward(int... args){
request = movingService.submit(new Runnable(){
public void run(){
Robot.this.move(args);
}
});
}
public void stop(){
request.cancel(true);
}
}
If I'm understanding you correctly then yes, you can call methods on an object from any given thread. However, for this to work in a bug free fashion the robot class needs to be thread safe.
Make sure all your calls to Robot come from a thread (a class extending Thread that you create) with permissions to make the calls. Add this method to your call.
Note: this code is far from perfect. But it may give you some ideas you can use in your application.
public void stop() throws NoPermissionException {
checkStopPermission(); // throws NoPermissionException
// rest of stop here as normal
}
/**
* Alternatively you could return a boolean for has permission and then throw the NoPermissionException up there.
*/
private void checkStopPermission() throws NoPermissionException() {
try {
Thread t = Thread.currentThread();
RobotRunnableThread rrt = (RobotRunnableThread)t; // may throw cast exception
if(!rrt.hasPermission(RobotRunnableThread.STOP_PERMISSION)) { // assume Permission enum in RobotRunnableThread
throw new NoPermissionExeception();
}
} catch(Exception e) { // perhaps catch the individual exception(s)?
throw new NoPermissionException();
}
}
You have to start a new background thread when you instantiate a Robot that would handle movement. The thread would sit there, waiting for a signal from forward or stop and do the appropriate thing.
You will have to synchronize the threads using either semaphores, wait handles, or other inter thread communication elements.
The least robust solution that wastes the most CPU (this is pseudo code since I have not used Java in a while, might be intermixed with .NET APIs):
public class Robot implements IRunnable {
public Robot() {
new Thread(this).Start();
}
private int direction = 0;
private int duration = 0;
private bool go = false;
public void Run() {
DateTime moveStartedAt;
bool moving = false;
while(true) {
if(go) {
if(moving) {
// we are already moving
if((DateTime.Now - moveStartedAt).Seconds >= duration) {
moving = false;
}
} else {
moveStartedAt = DateTime.Now;
moving = true;
}
} else {
moving = false;
}
}
}
public void forward(int direction, int duration) {
this.direction = direction;
this.duration = duration;
this.go = true;
}
public void stop() {
this.go = false;
}
}
(the above code should be modified to be Java for better answer)
What is wrong with this code:
The Run() method consumes one whole Core (it has no sleeps)
Calling stop() and then forward() right away can result in a race condition (the Run() has not seen the stop yet, but you already gave it another forward)
There is no way for Run() to exit
You can call forward() to redirect the move that is already in progress
Others?