How to synchronize the threads in the time Java - java

I study a thread and trying make a timer using thread. To the main thread wrote a time
public class A {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please, write the time in ms");
long time = Long.parseLong(reader.readLine());
B thread = new B();
int timer = 0;
try {
thread.start();
Thread.sleep(time);
timer=thread.stop();
}
catch(InterruptedException e) {
System.out.println("Oh....");
}
System.out.println("Result is "+timer);
}
}
and every millisecond program write a name of specific millisecond in child thread.
public class B implements Runnable {
private volatile boolean running=true;
private int timer=0;
Thread thread;
public B() {
thread = new Thread(this);
}
public void run() {
while (running) {
System.out.println(timer);
timer++;
try {
Thread.sleep(1);
}
catch(InterruptedException e) {
System.out.println("B");
}
}
}
public int stop() {
running = false;
return timer;
}
public void start() {
thread.start();
}
}
But when try with parameter 50 get the result 37. I want understand how to synchronize it in the time. Can you explain me how to do it correct?

When time is over just set the variable running to false,it will end the while loop and the child thread will also be finished.
So after below line, try to set running variable to false.(provide some setter method or may be in constructor argument)
Thread.sleep(time);

You are forgetting that all the statements other than Thread.sleep(1) also take time to execute. Most notably the System.out.println(timer): this is an I/O operation and whenever such an operation takes place, it usually sucks time (printing to screen makes the program wait for this blocking I/O operation to complete).
But I like to demonstrate a more subtle assumption: you also assume that when thread.start() returns, B.run() is executing. This is not the case, as is demonstrated in the following little program:
import java.util.concurrent.TimeUnit;
public class ThreadTimer implements Runnable {
public static void main(String[] args) {
ThreadTimer tt = new ThreadTimer();
long afterStart = 0L;
new Thread(tt).start();
afterStart = System.nanoTime();
println("After start: " + afterStart);
try {
Thread.sleep(100L);
} catch (Exception e) {
e.printStackTrace();
}
long deltaStart = tt.realStart - afterStart;
println("Delta start: " + deltaStart);
long deltaStartMs = TimeUnit.NANOSECONDS.toMillis(deltaStart);
println("Delta start ms.: " + deltaStartMs);
}
public long realStart;
#Override
public void run() {
realStart = System.nanoTime();
println("Real start : " + realStart);
}
private static void println(String msg) {
System.out.println(msg);
}
}
On my system this shows:
After start: 40062314666459
Real start : 40062314706827
Delta start: 40368
Delta start ms.: 0
Which means a little bit of time was lost. I'm sure that if you measure how long it takes to perform System.out.println(timer), you will see more little bits of time lost. All these little bits eventually add up to quite a chunk of time not accounted for.
On a final note: System.nanoTime() and System.currentTimeMillis() also take time to execute (it takes time to measure the time).

Related

How to call multiple functions which recur at regular intervals and takes long time to complete in Java?

I have a requirement to run a Java program with the following functionalities.
There should be a function (Say fetchTimeLimits()) that fetches two values of time. Time limit A and Time limit B. Note that both these time limits are future time values of the type Instant(). The fetching of these values should happen every 5 seconds.
There should be a function (Say functionA()) that utilizes time limit A. function A runs a while loop which sends out a calculated value until Time limit A is over. There is a sleep time of 1 second within the while loop.
There should be a function (Say functionB()) that utilizes time limit B. function B runs a while loop which sends out a calculated value until Time limit B is over. There is a sleep time of 1 second within while loop.
To implement this, I added a timer task with an interval of 5 seconds. In the timer task, fetchTimeLimits() function is called. Also, Two separate threads are started for functionA() and functinB(), if they are null or not alive. This is because, functionA() and functionB() would take hours to complete execution.
However, the CPU usage and RAM usage of the Java program is considerably high and I can observe that the CPU usage graph shows spikes.
package com.test;
import java.time.Instant;
import java.util.Timer;
import java.util.TimerTask;
public class mainClass {
static Thread functionAThread = null;
static Thread functionBThread = null;
static volatile Instant timeA = null;
static volatile Instant timeB = null;
static Timer timer = new Timer();
public static void main(String[] args) {
startTimer();
}
private static void startTimer() {
timer.schedule(new TimerTask() {
#Override
public void run() {
fetchTimeLimits();
if (functionAThread == null || !functionAThread.isAlive()) {
functionAThread = new Thread(() -> {
functionA();
});
functionAThread.start();
}
if (functionBThread == null || !functionBThread.isAlive()) {
functionBThread = new Thread(() -> {
functionB();
});
functionBThread.start();
}
}
}, 0, 5000);
}
private static void fetchTimeLimits() {
// Fetch values of timeA and timeB
}
private static void functionA() {
while (timeA != null && timeA.compareTo(Instant.now()) > 0) {
try {
Thread.sleep(1000);
// Calculate a value and send it.
} catch (InterruptedException e) {
}
}
}
private static void functionB() {
while (timeB != null && timeB.compareTo(Instant.now()) > 0) {
try {
Thread.sleep(1000);
// Calculate a value and send it.
} catch (InterruptedException e) {
}
}
}
}
Is there a better way to handle the requirement?

Java: two threads printing & receiving user input via Scanner: program doesn't exit after exception is thrown

I have this program with two threads: lessonThread and questionThread. The lesson thread prints Lesson continues, while the question thread every 5 seconds asks Finish lesson? and asks a user for input via Scanner. I have a wait() call in questionThread that throws an exception. In the catch block I use System.exit() to terminate the program, however it doesn't work right away - only after many lesson messages. At the same time, if I go through breakpoints in both thread in a debugger, it System.exit() terminates the program very soon.
public class LessonNotify {
private volatile boolean finished;
private Scanner scanner = new Scanner(System.in);
private Thread lessonThread;
private Thread questionThread;
public static void main(String[] args) {
LessonNotify lesson = new LessonNotify();
lesson.lessonThread = lesson.new LessonThread();
lesson.questionThread = lesson.new QuestionThread();
lesson.lessonThread.start();
lesson.questionThread.start();
}
class LessonThread extends Thread {
#Override
public void run() {
while (!finished) {
System.out.println("Lesson continues");
}
}
}
class QuestionThread extends Thread {
private Instant sleepStart = Instant.now();
#Override
public void run() {
while (!finished) {
if (Instant.now().getEpochSecond() - sleepStart.getEpochSecond() >= 5) {
try {
lessonThread.wait();
} catch (Exception e) {
e.printStackTrace();
finished = true;
System.exit(0);
}
System.out.print("Finish a lesson? y/n");
String reply = scanner.nextLine().substring(0, 1);
switch (reply.toLowerCase()) {
case "y":
finished = true;
}
sleepStart = Instant.now();
lessonThread.notify();
}
}
}
}
}
That's just how exiting works. The messages printed by the other thread, especially because it has no breaks on the car, are already in various buffers. By using a debugger the thread is frozen or at least runs slower, thus, you don't observe it.
See my other answer. When I said 'this is not how you thread' - there are a billion reasons why, and this is one of the billion.

how do i add a number to an integer every second

I'm making a cookie clicker sort of game and I want a thing where every second a certain number let's say 5 is added to another number. So every second the integer variable is going up by 5. How would I create a sort of time measuring method where it measures time so I can add a number to another number.
public class timeTesting {
// I've put this method here for someone to create
// a timer thing
void timer()
{
}
public static void main(String[] args) {
// Original number
int number = 1;
// Number I want added on to the original number every 5 seconds
int addedNumber = 5;
}
}
You can use Timer to schedule a TimerTask who has the desired code inside the run() method. Check the code below (run() will be called once after 5000 milliseconds) :
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
number += addedNumber;
}
}, 5000);
Also you can use scheduleAtFixedRate(TimerTask task, long delay, long period) for repetitive tasks (here run will be called immediately, and every 5000 milliseconds):
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
number += addedNumber;
}
}, 0, 5000);
If you're targeting the android platform you could use CountDownTimer, which allows you to execute some code every certain amount of time for a certain duration. But be aware that android doesn't work with the main method like J2SE does.
Anyway, if you're looking foward to program an android game, i'd highly recommend you to start here: Android Development
I'd like to suggest start studying RxJava. Reactive programming is very powerful for games development: https://www.youtube.com/watch?v=WKore-AkisY
With RxJava, your problem can be solved with Observable interval() method:
https://github.com/Netflix/RxJava/wiki/Creating-Observables#interval
Ivan
You should consider using a Timer which will fire an event when a certain time interval has passed. It can repeat the event every so often, too.
Not very elegant, but working code:
public class MyTimer {
private volatile int number; //must be volatile as we're working on multiple threads.
private final int numberToAdd;
private final long timerTimeInMillis;
public MyTimer() {
number = 1;
numberToAdd = 5;
timerTimeInMillis = 5000;
}
public void runTimer() {
new Thread() { //declaring a new anonymous Thread class
public void run() { //that has to override run method.
while (true) //run the program in an infinite loop
{
number += numberToAdd; //add a number
System.out.println("Added number. Now the number is: " + number);
try {
Thread.sleep(timerTimeInMillis); //and then sleep for a given time.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start(); //and here we're starting this declared thread
}
public static void main(String[] args)
{
new MyTimer().runTimer();
try {
Thread.sleep(100000); //this application will work for 100sec.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Using java.util.Timer would be more elegant, but in here you may get aquainted with anonymous classes.

Two threads deadlocking but can't see why, lock released with notifyAll()

using JConsole it seems i get a deadlock situation when 2 threads try to modify this object.
package com.steven.concurrent.assignment2.memoryallocator;
/*
* This seems to deadlock... cant see why though.
*/
public class MemAllocMonitor implements IMemoryAllocator {
private final int MAX_FREE = 50;
private int freePages = MAX_FREE;
//I think this would work, without even the need for sync blocks.....
// But only in the situaion where i would not have to check the bounds of the updates. If it was just modification, this would be
// fine....
//private volatile int freePages = 50;
public MemAllocMonitor(int pages){
assert(pages < MAX_FREE);
this.freePages = pages;
}
public MemAllocMonitor(){
}
#Override
public synchronized void request(int number) {
if(number < 0)
throw new IllegalArgumentException();
while(freePages - number < 0) {
System.out.println("No space....waiting...");
try {
this.wait();
} catch (Exception e) {}
}
freePages -= number;
System.out.println("Requested : " + number + " remaining " + freePages);
this.notifyAll();
}
#Override
public synchronized void release(int number) {
if(number < 0)
throw new IllegalArgumentException();
while(freePages + number > MAX_FREE) {
System.out.println("page table full....would be " + (number + freePages) );
try {
this.wait();
} catch (Exception e) {}
}
freePages += number;
System.out.println("Released : " + number + " remaining " + freePages);
this.notifyAll();
}
#Override
public int getFreePages() {
return freePages;
}
}
This object is accessed via a simple wrapper that implements runnable, and calls either method as shown below.
package com.steven.concurrent.assignment2.memoryallocator;
import concurrent.RandomGenerator;
import concurrent.Time;
public class MemAllocRequester implements Runnable, MemoryAllocatorAction{
private IMemoryAllocator memoryAllocator;
private volatile boolean shutdown = false;;
public MemAllocRequester(IMemoryAllocator memAlloc){
this.memoryAllocator = memAlloc;
}
#Override
public void run() {
while(!shutdown){
Time.delay(500);
memoryAllocator.request(RandomGenerator.integer(0, 30));
}
}
public void ShutDown(){
this.shutdown = true;
}
}
and
package com.steven.concurrent.assignment2.memoryallocator;
import concurrent.RandomGenerator;
import concurrent.Time;
public class MemAllocReleaser implements Runnable, MemoryAllocatorAction{
private IMemoryAllocator memoryAllocator;
private volatile boolean shutdown = false;;
public MemAllocReleaser(IMemoryAllocator memAlloc){
this.memoryAllocator = memAlloc;
}
#Override
public void run() {
while(!shutdown){
Time.delay(500);
memoryAllocator.release(RandomGenerator.integer(0, 30));
}
}
public void ShutDown(){
this.shutdown = true;
}
}
It is started off as such...
package com.steven.concurrent.assignment2.memoryallocator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MemAllocMain {
public static void main(String[] args){
ExecutorService executor = Executors.newFixedThreadPool(10);
//IMemoryAllocator memoryAllocator = new MemAllocSemaphore();
IMemoryAllocator memoryAllocator = new MemAllocMonitor();
System.out.println("Starting app with " + memoryAllocator.getFreePages() + " pages...");
Thread t1 = new Thread(new MemAllocRequester(memoryAllocator));
Thread t2 = new Thread(new MemAllocReleaser(memoryAllocator));
t1.setName("MEMORY REQUESTER £££££££££££££££££££");
t2.setName("MEMORY RELEASER £££££££££££££££££££");
executor.submit(t1);
executor.submit(t2);
}
}
I have implemented a solution using the semaphore class, but for some reason this is causing trouble using the default java monitor solution. It runs for about 30 seconds, then both threads go into their waiting state, even though the lock should be enforced.
The problem is that both threads are hitting the upper and lower bounds (50 and 0 respectively) at the same time. Both examples below highlight the deadlock.
Scenario 1
request(29) - freePages=21
request(30) - under 0 so waits
release(30) - over 50 so waits : deadlock
Scenario 2
request(29) - freePages=21
release(30) - over 50 so waits
request(30) - under 0 so waits : deadlock
I am not sure what the exact requirements are for the homework problem but you need to revisit the release and request methods. I see two viable solutions:
Change the release method so that it only releases up to MAX_FREE but will still return
Change the release method so that it can release a subset of the amount requested, notifyAll, reenter the wait so it can release the remaining amount.
Also, you are kind of using the ExecutionService wrong. The ExecutionService is what creates the Threads so there is no reason for you to create the threads like you are doing.
Thread t1 = new Thread(new MemAllocRequester(memoryAllocator));
Thread t2 = new Thread(new MemAllocReleaser(memoryAllocator));
The threads you are creating will actually never be 'started' as Threads. It is still working for you because the ExecutionService threads will call your Thread.run() which will call MemAlloc*.run(). i.e. your t1 and t2 threads just pass the run() call along and provide no value.
Your MemAllocRequester and MemAllocReleaser are Runnables so just pass those into the ExecutionService directly.
executor.submit(new MemAllocRequester(memoryAllocator));
executor.submit(new MemAllocReleaser(memoryAllocator));

I get exception when using Thread.sleep(x) or wait()

I have tried to delay - or put to sleep - my Java program, but an error occurs.
I'm unable to use Thread.sleep(x) or wait(). The same error message appears:
unreported exception java.lang.InterruptedException; must be caught or declared to be thrown.
Is there any step required before using the Thread.sleep() or wait() methods?
You have a lot of reading ahead of you. From compiler errors through exception handling, threading and thread interruptions. But this will do what you want:
try {
Thread.sleep(1000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
As other users have said you should surround your call with a try{...} catch{...} block. But since Java 1.5 was released, there is TimeUnit class which do the same as Thread.sleep(millis) but is more convenient.
You can pick time unit for sleep operation.
try {
TimeUnit.NANOSECONDS.sleep(100);
TimeUnit.MICROSECONDS.sleep(100);
TimeUnit.MILLISECONDS.sleep(100);
TimeUnit.SECONDS.sleep(100);
TimeUnit.MINUTES.sleep(100);
TimeUnit.HOURS.sleep(100);
TimeUnit.DAYS.sleep(100);
} catch (InterruptedException e) {
//Handle exception
}
Also it has additional methods:
TimeUnit Oracle Documentation
Have a look at this excellent brief post on how to do this properly.
Essentially: catch the InterruptedException. Remember that you must add this catch-block. The post explains this a bit further.
Use the following coding construct to handle exceptions
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
//Handle exception
}
Put your Thread.sleep in a try catch block
try {
//thread to sleep for the specified number of milliseconds
Thread.sleep(100);
} catch ( java.lang.InterruptedException ie) {
System.out.println(ie);
}
When using Android (the only time when I use Java) I would recommend using a handler instead putting the thread to sleep.
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Log.i(TAG, "I've waited for two hole seconds to show this!");
}
}, 2000);
Reference: http://developer.android.com/reference/android/os/Handler.html
Try this:
try{
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Exception caught");
}
My ways to add delay to a Java program.
public void pause1(long sleeptime) {
try {
Thread.sleep(sleeptime);
} catch (InterruptedException ex) {
//ToCatchOrNot
}
}
public void pause2(long sleeptime) {
Object obj = new Object();
if (sleeptime > 0) {
synchronized (obj) {
try {
obj.wait(sleeptime);
} catch (InterruptedException ex) {
//ToCatchOrNot
}
}
}
}
public void pause3(long sleeptime) {
expectedtime = System.currentTimeMillis() + sleeptime;
while (System.currentTimeMillis() < expectedtime) {
//Empty Loop
}
}
This is for sequential delay but for Loop delays refer to Java Delay/Wait.
public static void main(String[] args) throws InterruptedException {
//type code
short z=1000;
Thread.sleep(z);/*will provide 1 second delay. alter data type of z or value of z for longer delays required */
//type code
}
eg:-
class TypeCasting {
public static void main(String[] args) throws InterruptedException {
short f = 1;
int a = 123687889;
short b = 2;
long c = 4567;
long d=45;
short z=1000;
System.out.println("Value of a,b and c are\n" + a + "\n" + b + "\n" + c + "respectively");
c = a;
b = (short) c;
System.out.println("Typecasting...........");
Thread.sleep(z);
System.out.println("Value of B after Typecasting" + b);
System.out.println("Value of A is" + a);
}
}
A simpler way to wait is to use System.currentTimeMillis(), which returns the number of milliseconds since midnight on January 1, 1970 UTC. For example, to wait 5 seconds:
public static void main(String[] args) {
//some code
long original = System.currentTimeMillis();
while (true) {
if (System.currentTimeMillis - original >= 5000) {
break;
}
}
//more code after waiting
}
This way, you don't have to muck about with threads and exceptions.
Hope this helps!
Use java.util.concurrent.TimeUnit:
TimeUnit.SECONDS.sleep(1);
Sleep for one second or
TimeUnit.MINUTES.sleep(1);
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][1] and either [scheduleAtFixedRate][2] or [scheduleWithFixedDelay][3].
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");
}
Thread.sleep() is simple for the beginners and may be appropriate for unit tests and proofs of concept.
But please DO NOT use sleep() for production code. Eventually sleep() may bite you badly.
Best practice for multithreaded/multicore java applications to use the "thread wait" concept. Wait releases all the locks and monitors held by the thread, which allows other threads to acquire those monitors and proceed while your thread is sleeping peacefully.
Code below demonstrates that technique:
import java.util.concurrent.TimeUnit;
public class DelaySample {
public static void main(String[] args) {
DelayUtil d = new DelayUtil();
System.out.println("started:"+ new Date());
d.delay(500);
System.out.println("half second after:"+ new Date());
d.delay(1, TimeUnit.MINUTES);
System.out.println("1 minute after:"+ new Date());
}
}
DelayUtil implementation:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class DelayUtil {
/**
* Delays the current thread execution.
* The thread loses ownership of any monitors.
* Quits immediately if the thread is interrupted
*
* #param durationInMillis the time duration in milliseconds
*/
public void delay(final long durationInMillis) {
delay(durationInMillis, TimeUnit.MILLISECONDS);
}
/**
* #param duration the time duration in the given {#code sourceUnit}
* #param unit
*/
public void delay(final long duration, final TimeUnit unit) {
long currentTime = System.currentTimeMillis();
long deadline = currentTime+unit.toMillis(duration);
ReentrantLock lock = new ReentrantLock();
Condition waitCondition = lock.newCondition();
while ((deadline-currentTime)>0) {
try {
lock.lockInterruptibly();
waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
} finally {
lock.unlock();
}
currentTime = System.currentTimeMillis();
}
}
}
Alternatively, if you don't want to deal with threads, try this method:
public static void pause(int seconds){
Date start = new Date();
Date end = new Date();
while(end.getTime() - start.getTime() < seconds * 1000){
end = new Date();
}
}
It starts when you call it, and ends when the number of seconds have passed.

Categories

Resources