Odd behavior with Runnable and ExecutorService - java

I'm getting some really weird behavior with multithreading. I have two classes: DipoleTester and Dipole.
DipoleTester attempts to create several Dipole objects, and then run them asynchronously. The problem is that DipoleTester just runs all of its Dipole objects at once, rather than 2 at a time.
Here is DipoleTester:
public class DipoleTester {
public static String DIR = "./save/";
public static void main(String[] args) throws InterruptedException {
Dipole trial;
ExecutorService service = Executors.newFixedThreadPool(2);
for (int r = 10; r < 13; r += 1) {
double radius = (double) r / 10000.0;
for (int matType = 0; matType < 3; matType++) {
String name = "Simple_mat"+matType + "_rad" + radius;
trial = new DipoleSimple(DIR + "Simple/", name);
trial.materialType = matType;
trial.RADIUS = radius;
service.submit(trial);
}
}
service.shutdown();
service.awaitTermination(100, TimeUnit.HOURS);
}
}
And here are the (relevant bits) from Dipole
public abstract class Dipole implements Runnable{
...
public void run() {
initiate();
}
public void initiate() {
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date) + ": Starting: " + NAME);
model = ModelUtil.create(NAME);
model.modelNode().create("mod1");
makeParams();
makeVariables();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
...
}
The problem now is that all the threads execute at once, even with the thread.sleep(5000)! I have no idea what's going on. Here is the console output:
05/08/2013 19:17:31: Starting: Simple_mat0_rad0.001
05/08/2013 19:17:31: Starting: Simple_mat1_rad0.001
05/08/2013 19:17:31: Starting: Simple_mat2_rad0.001
05/08/2013 19:17:31: Starting: Simple_mat0_rad0.0011
05/08/2013 19:17:31: Starting: Simple_mat1_rad0.0011
05/08/2013 19:17:31: Starting: Simple_mat2_rad0.0011
05/08/2013 19:17:31: Starting: Simple_mat0_rad0.0012
05/08/2013 19:17:31: Starting: Simple_mat1_rad0.0012
05/08/2013 19:17:31: Starting: Simple_mat2_rad0.0012

Your Runnable task is throwing an exception before it gets to the Thread.sleep() call. This allows the next task to begin execution. All the tasks fail in such quick succession that all appear to run concurrently.
Make the call to Thread.sleep() the first thing you do in your run() method and you will see that only two threads run at a time.
To detect such failures, you'll need to examine the Future instance that results from each call to submit(). There are other methods for submitting a list of tasks in bulk, and waiting for them to complete, that might be better suited to your application.

Related

How to execute something every 10 seconds? [duplicate]

This question already has answers here:
What is 'scope' in Java?
(2 answers)
Closed 2 years ago.
I would like to execute a piece of code every 10 seconds. I have found an example on this forum, but have some issues with my implementation.
package robomow;
import robomow.SI7021;
import robomow.SGP30;
import com.pi4j.io.i2c.I2CFactory;
import java.io.IOException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Environment {
long delay = 10000;
LoopTask task = new LoopTask();
Timer timer = new Timer("TaskName");
public void start() {
timer.cancel();
timer = new Timer("Environment");
SI7021 si7021 = new SI7021();
SGP30 sgp30 = new SGP30();
Date executionDate = new Date();
timer.scheduleAtFixedRate(task, executionDate, delay);
}
private class LoopTask extends TimerTask {
public void run() {
System.out.printf("Humidity = %.0f Temperature = %.2f \n", si7021.GetHumidity(), si7021.GetTemperature());
System.out.printf("eCO2 = %d ppm TVOC = %d \n", sgp30.getECO2(), sgp30.getTVOC());
}
}
public static void main(String[] args) throws InterruptedException,
IOException,
I2CFactory.UnsupportedBusNumberException {
Environment EnvironmentTask = new Environment();
SI7021 si7021 = new SI7021();
SGP30 sgp30 = new SGP30();
EnvironmentTask.start();
}
}
I get this error, pointing to si7021:
Environment.java:28: error: cannot find symbol
System.out.printf("Humidity = %.0f Temperature = %.2f \n", si7021.GetHumidity(), si7021.GetTemperature());
The variables you are declaring cannot be accessed inside the TimerTask; you should consider moving them inside the class.
private class LoopTask extends TimerTask {
SI7021 si7021;
SGP30 sgp30;
public LoopTask() {
try {
si7021 = new SI7021();
sgp30 = new SGP30();
} catch(Exception e){
//handle exception
}
}
public void run() {
System.out.printf("Humidity = %.0f Temperature = %.2f \n", si7021.GetHumidity(), si7021.GetTemperature());
System.out.printf("eCO2 = %d ppm TVOC = %d \n", sgp30.getECO2(), sgp30.getTVOC());
}
}
The Answer by iota correctly solved your direct problem. But looking at the bigger picture, you are using obsolete classes. The modern approach with executor service and runnable is easier and simpler.
Avoid the legacy classes
The Timer and TimerTask classes were supplanted with the executor service framework in Java 5 and later.
Likewise, the terrible Date class was supplanted years ago by the modern java.time classes defined in JSR 310. Replaced specifically by java.time.Instant.
Environment class
Let's define your Environment class. This class monitors two pieces of equipment that sample the environment, and reports the current readings when asked via its report method.
package work.basil.example;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.*;
public class Environment
{
private SI7021 si7021 = new Environment.SI7021();
private SGP30 sgp30 = new Environment.SGP30();
public void report ( )
{
System.out.println( "------------| Environment Report at " + Instant.now().truncatedTo( ChronoUnit.SECONDS ) + " |------------------------" );
System.out.printf( "Humidity = %.0f Temperature = %.2f \n" , si7021.getHumidity() , si7021.getTemperature() );
System.out.printf( "eCO2 = %d ppm TVOC = %d \n" , sgp30.getECO2() , sgp30.getTVOC() );
}
class SI7021
{
public float getHumidity ( )
{
return ThreadLocalRandom.current().nextFloat() * 100;
}
public float getTemperature ( )
{
return ThreadLocalRandom.current().nextFloat() * 100;
}
}
class SGP30
{
public int getECO2 ( )
{
return ThreadLocalRandom.current().nextInt( 1 , 100 );
}
public int getTVOC ( )
{
return ThreadLocalRandom.current().nextInt( 1 , 100 );
}
}
}
Runnable
Define your task as a Runnable object having a run method.
Using lambda syntax, that would simply be:
Runnable task = ( ) -> environment.report() ;
Or use a method reference.
Runnable task = environment :: report ;
Or, if you are not comfortable with the modern syntax, use an anonymous class.
Runnable task = new Runnable()
{
#Override
public void run ( )
{environment.report();}
};
Scheduled executor service
The ScheduledExecutorService interface repeatedly runs a task, a Runnable. You have a choice of scheduleAtFixedRate​ or scheduleWithFixedDelay, so read the Javadoc to decide which kind of cadence fits your needs.
Be sure to gracefully shutdown your executor service. Otherwise, its backing thread pool may run indefinitely, like a zombie 🧟‍♂️. We use a try-finally to make sure the executor service is shutdown. FYI, in the future when Project Loom arrives, ExecutorService will be AutoCloseable. We will then be able to use try-with-resources syntax for simpler approach to do the shutdown.
public static void main ( String[] args )
{
System.out.println( "INFO - Starting the scheduled executor service generating Environment reports. " + Instant.now() );
ScheduledExecutorService scheduledExecutorService = null;
try
{
Environment environment = new Environment();
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
Runnable task = environment :: report ;
scheduledExecutorService.scheduleAtFixedRate(
task , // Implements `Runnable`.
0 , // Initial delay.
Duration.ofSeconds( 10 ).toSeconds() , // Period
TimeUnit.SECONDS ) // Unit of time for both delay and period.
;
// … do other stuff
try { Thread.sleep( Duration.ofMinutes( 1 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); } // Give our demo a chance to run a while.
System.out.println( "INFO - Will shutdown the scheduled executor service generating Environment reports. " + Instant.now() );
}
finally
{
if ( Objects.nonNull( scheduledExecutorService ) ) { scheduledExecutorService.shutdown(); }
}
}
When run:
INFO - Starting the scheduled executor service generating Environment reports. 2021-01-04T07:46:54.494330Z
------------| Environment Report at 2021-01-04T07:46:54Z |------------------------
Humidity = 95 Temperature = 40.71
eCO2 = 99 ppm TVOC = 1
------------| Environment Report at 2021-01-04T07:47:04Z |------------------------
Humidity = 72 Temperature = 92.15
eCO2 = 25 ppm TVOC = 42
------------| Environment Report at 2021-01-04T07:47:14Z |------------------------
Humidity = 52 Temperature = 94.01
eCO2 = 85 ppm TVOC = 89
------------| Environment Report at 2021-01-04T07:47:24Z |------------------------
Humidity = 80 Temperature = 1.60
eCO2 = 10 ppm TVOC = 78
------------| Environment Report at 2021-01-04T07:47:34Z |------------------------
Humidity = 64 Temperature = 44.97
eCO2 = 50 ppm TVOC = 40
------------| Environment Report at 2021-01-04T07:47:44Z |------------------------
Humidity = 1 Temperature = 31.63
eCO2 = 20 ppm TVOC = 69
------------| Environment Report at 2021-01-04T07:47:54Z |------------------------
Humidity = 30 Temperature = 26.88
eCO2 = 2 ppm TVOC = 86
INFO - Will shutdown the scheduled executor service generating Environment reports. 2021-01-04T07:47:54.516543Z
In real work, surround the innards of your Runnable with a try-catch to catch any unexpected exceptions (and maybe errors). An exception/error bubbling all the way up to the scheduled executor service causes the service to halt silently, with no further executions performed.
You need a class that extends TimerTask and override the public void run() method, which will be executed everytime you pass an instance of that class to timer.schedule() method.
class Hello extends TimerTask {
public void run() {
System.out.println("Hello World!");
}
}
// And From your main() method or any other method
Timer timer = new Timer();
timer.schedule(new Hello(), 0, 100000);//10 Min

How do I let delete my java discord bots automaticly after 5 seconds?

How do I let my discord java bot to delete the message after for example 5 seconds???
String[] messageArgs = event.getMessage().getContentRaw().toLowerCase().split(" ");
for (String args : messageArgs) {
if (blacklistWords.contains(args)) {
if (memberRoles.contains(warn0)) {
event.getMessage().delete().queue();
event.getMessage().getChannel().sendMessage
("**" + MemberMention + "** unterlasse bitte diese **Wortwahl.**"
+ "\nBei **3 Verwarnungen** wirst du **gekickt!**").queue();
event.getGuild().addRoleToMember(user, warn1).complete();
event.getJDA().getGuildById(Secrets.guildID).removeRoleFromMember(user, warn0).complete();
break;
}
}
}
The proper way to do this would be to pass a consumer to your .queue method when sending the message. Together with using RestAction#queueAfter you would get
channel.sendMessage("message").queue(message -> message.delete().queueAfter(5,
TIMEUNIT.SECONDS);
see queue with Consumer and queueAfter.
There is another way of doing this using RestAction#delay
You can start a new thread and pause that thread before running the delete command on the message. That way you won't cause issues with the other code lines.
String[] messageArgs = event.getMessage().getContentRaw().toLowerCase().split(" ");
for (String args : messageArgs) {
if (blacklistWords.contains(args)) {
if (memberRoles.contains(warn0)) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
// pause for 5 seconds
wait(5000);
event.getMessage().delete().queue();
event.getMessage().getChannel().sendMessage
("**" + MemberMention + "** unterlasse bitte diese **Wortwahl.**"
> here + "\nBei **3 Verwarnungen** wirst du **gekickt!**").queue();
event.getGuild().addRoleToMember(user, warn1).complete();
event.getJDA().getGuildById(Secrets.guildID).removeRoleFromMember(user, warn0)
.complete();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(r);
t.start();
break;
}
}
}
Just put a pause in with something like Thread.sleep(5000); before you call the function to delete the message. This will pause for 5000 milliseconds or 5 seconds.

How do I timeout a method after fixed time in java using concurrency executor future?

Using java concurrent executor, future cancel method not stopping the current task.
I have followed this solution of timeout and stop processing of current task. But it doesn't stop the processing.
I am trying this with cron job. Every 30 seconds my cron job gets executed and I am putting 10 seconds timeout. Debug comes in future cancel method, but it is not stopping current task.
Thank you.
#Scheduled(cron = "*/30 * * * * *")
public boolean cronTest()
{
System.out.println("Inside cron - start ");
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date));
System.out.println("Inside cron - end ");
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
int i=1;
while(i<100)
{
System.out.println("i: "+ i++);
try {
TimeUnit.SECONDS.sleep(1);
}
catch(Exception e)
{
}
}
return null;
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(10, TimeUnit.SECONDS);
} catch (Exception e)
} finally {
future.cancel(true);
return true;
}
}
The expected result is cron job runs every 30 seconds and after 10 seconds it should time out and wait for approximately 20 seconds for a cron job to start again. And should not continue the older loop because we have timeout on 10 seconds.
Current result is:
Inside cron - start
2019/07/25 11:09:00
Inside cron - end
i: 1
i: 2
i: 3
i: 4 ... upto i: 31
Inside cron - start
2019/07/25 11:09:30
Inside cron - end
i: 1
i: 32
i: 2
i: 3
i: 33
...
Expected result is:
Inside cron - start
2019/07/25 11:09:00
Inside cron - end
i: 1
i: 2
i: 3
i: 4 ... upto i: 10
Inside cron - start
2019/07/25 11:09:30
Inside cron - end
i: 1
i: 2
i: 3 ... upto i:10
The first problem is in this part of code:
catch(Exception e)
{
}
When you invoke future.cancel(true); your thread is being interrupted with Thread.interrupt()
Which means that when a thread is sleeping, it gets awoken and throws InterruptedException which is caught by the catch block and ignored. To fix this problem you have to handle this exception:
catch(InterruptedException e) {
break; //breaking from the loop
}
catch(Exception e)
{
}
The second problem: Thread.interrupt() may be invoked while the thread is not sleeping. In this case InterruptedException is not thrown. Instead, the interrupted flag of the thread is raised. What you have to do is to check for this flag from time to time, and if it's raised, handle interruption. The basic code for it would look like:
try {
if (Thread.currentThread().isInterrupted()) {
break;
}
TimeUnit.SECONDS.sleep(1);
}
...
// rest of the code
UPDATE:
Here's the full code of Callable:
Callable<Object> task = new Callable<Object>() {
public Object call() {
int i=1;
while(i<100)
{
System.out.println("i: "+ i++);
try {
if (Thread.currentThread().isInterrupted()) {
break; //breaking from the while loop
}
TimeUnit.SECONDS.sleep(1);
} catch(InterruptedException e) {
break; //breaking from the while loop
} catch(Exception e)
{
}
}
return null;
}
};

How to change execution speed? [duplicate]

If you had read my other question, you'll know I've spent this weekend putting together a 6502 CPU emulator as a programming exercise.
The CPU emulator is mostly complete, and seems to be fairly accurate from my limited testing, however it is running incredibly fast, and I want to throttle it down to the actual clock speed of the machine.
My current test loop is this:
// Just loop infinitely.
while (1 == 1)
{
CPU.ClockCyclesBeforeNext--;
if (CPU.ClockCyclesBeforeNext <= 0)
{
// Find out how many clock cycles this instruction will take
CPU.ClockCyclesBeforeNext = CPU.OpcodeMapper.Map[CPU.Memory[CPU.PC]].CpuCycles;
// Run the instruction
CPU.ExecuteInstruction(CPU.Memory[CPU.PC]);
// Debugging Info
CPU.DumpDebug();
Console.WriteLine(CPU.OpcodeMapper.Map[CPU.Memory[CPU.PC]].ArgumentLength);
// Move to next instruction
CPU.PC += 1 + CPU.OpcodeMapper.Map[CPU.Memory[CPU.PC]].ArgumentLength;
}
}
As you can tell, each opcode takes a specific amount of time to complete, so I do not run the next instruction until I count down the CPU Cycle clock. This provides proper timing between opcodes, its just that the entire thing runs way to fast.
The targeted CPU speed is 1.79mhz, however I'd like whatever solution to the clock issue to keep the speed at 1.79mhz even as I add complexity, so I don't have to adjust it up.
Any ideas?
I wrote a Z80 emulator many years ago, and to do cycle accurate execution, I divided the clock rate into a number of small blocks and had the core execute that many clock cycles. In my case, I tied it to the frame rate of the game system I was emulating. Each opcode knew how many cycles it took to execute and the core would keep running opcodes until the specified number of cycles had been executed. I had an outer run loop that would run the cpu core, and run other parts of the emulated system and then sleep until the start time of the next iteration.
EDIT: Adding example of run loop.
int execute_run_loop( int cycles )
{
int n = 0;
while( n < cycles )
{
/* Returns number of cycles executed */
n += execute_next_opcode();
}
return n;
}
Hope this helps.
Take a look at the original quicktime documentation for inspiration.
It was written a long time ago, when displaying video meant just swapping still frames at high enough speed, but the Apple guys decided they needed a full time-management framework. The design at first looks overengineered, but it let them deal with widely different speed requirements and keep them tightly synchronized.
you're fortunate that 6502 has deterministic time behaviour, the exact time each instruction takes is well documented; but it's not constant. some instructions take 2 cycles, other 3. Just like frames in QuickTime, a video doesn't have a 'frames per second' parameter, each frame tells how long it wants to be in screen.
Since modern CPU's are so non-deterministic, and multitasking OS's can even freeze for a few miliseconds (virtual memory!), you should keep a tab if you're behind schedule, or if you can take a few microseconds nap.
As jfk says, the most common way to do this is tie the cpu speed to the vertical refresh of the (emulated) video output.
Pick a number of cycles to run per video frame. This will often be machine-specific but you can calculate it by something like :
cycles = clock speed in Hz / required frames-per-second
Then you also get to do a sleep until the video update is hit, at which point you start the next n cycles of CPU emulation.
If you're emulating something in particular then you just need to look up the fps rate and processor speed to get this approximately right.
EDIT: If you don't have any external timing requirements then it is normal for an emulator to just run as fast as it possibly can. Sometimes this is a desired effect and sometimes not :)
I would use the clock cycles to calculate time and them sleep the difference in time. Of course, to do this, you need a high-resolution clock. They way you are doing it is going to spike the CPU in spinning loops.
Yes, as said before most of the time you don't need a CPU emulator to emulate instructions at the same speed of the real thing. What user perceive is the output of the computation (i.e. audio and video outputs) so you only need to be in sync with such outputs which doesn't mean you must have necessarily an exact CPU emulation speed.
In other words, if the frame rate of the video input is, let's say, 50Hz, then let the CPU emulator run as fast as it can to draw the screen but be sure to output the screen frames at the correct rate (50Hz). From an external point of view your emulator is emulating at the correct speed.
Trying to be cycle exact even in the execution time is a non-sense on a multi-tasking OS like Windows or Linux because the emulator instruction time (tipically 1uS for vintage 80s CPUs) and the scheduling time slot of the modern OS are comparable.
Trying to output something at a 50Hz rate is a much simpler task you can do very good on any modern machine
Another option is available if audio emulation is implemented, and if audio output is tied to the system/CPU clock. In particular I know that this is the case with the 8-bit Apple ][ computers.
Usually sound is generated in buffers of a fixed size (which is a fixed time), so operation (generation of data etc) of these buffers can be tied to CPU throughput via synchronization primitives.
I am in the process of making something a little more general use case based, such as the ability to convert time to an estimated amount of instructions and vice versa.
The project homepage is # http://net7mma.codeplex.com
The code starts like this: (I think)
#region Copyright
/*
This file came from Managed Media Aggregation, You can always find the latest version # https://net7mma.codeplex.com/
Julius.Friedman#gmail.com / (SR. Software Engineer ASTI Transportation Inc. http://www.asti-trans.com)
Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction,
* including without limitation the rights to :
* use,
* copy,
* modify,
* merge,
* publish,
* distribute,
* sublicense,
* and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
*
* JuliusFriedman#gmail.com should be contacted for further details.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE,
* ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* v//
*/
#endregion
namespace Media.Concepts.Classes
{
//Windows.Media.Clock has a fairly complex but complete API
/// <summary>
/// Provides a clock with a given offset and calendar.
/// </summary>
public class Clock : Media.Common.BaseDisposable
{
static bool GC = false;
#region Fields
/// <summary>
/// Indicates when the clock was created
/// </summary>
public readonly System.DateTimeOffset Created;
/// <summary>
/// The calendar system of the clock
/// </summary>
public readonly System.Globalization.Calendar Calendar;
/// <summary>
/// The amount of ticks which occur per update of the <see cref="System.Environment.TickCount"/> member.
/// </summary>
public readonly long TicksPerUpdate;
/// <summary>
/// The amount of instructions which occured when synchronizing with the system clock.
/// </summary>
public readonly long InstructionsPerClockUpdate;
#endregion
#region Properties
/// <summary>
/// The TimeZone offset of the clock from UTC
/// </summary>
public System.TimeSpan Offset { get { return Created.Offset; } }
/// <summary>
/// The average amount of operations per tick.
/// </summary>
public long AverageOperationsPerTick { get { return InstructionsPerClockUpdate / TicksPerUpdate; } }
/// <summary>
/// The <see cref="System.TimeSpan"/> which represents <see cref="TicksPerUpdate"/> as an amount of time.
/// </summary>
public System.TimeSpan SystemClockResolution { get { return System.TimeSpan.FromTicks(TicksPerUpdate); } }
/// <summary>
/// Return the current system time in the TimeZone offset of this clock
/// </summary>
public System.DateTimeOffset Now { get { return System.DateTimeOffset.Now.ToOffset(Offset).Add(new System.TimeSpan((long)(AverageOperationsPerTick / System.TimeSpan.TicksPerMillisecond))); } }
/// <summary>
/// Return the current system time in the TimeZone offset of this clock converter to UniversalTime.
/// </summary>
public System.DateTimeOffset UtcNow { get { return Now.ToUniversalTime(); } }
//public bool IsUtc { get { return Offset == System.TimeSpan.Zero; } }
//public bool IsDaylightSavingTime { get { return Created.LocalDateTime.IsDaylightSavingTime(); } }
#endregion
#region Constructor
/// <summary>
/// Creates a clock using the system's current timezone and calendar.
/// The system clock is profiled to determine it's accuracy
/// <see cref="System.DateTimeOffset.Now.Offset"/>
/// <see cref="System.Globalization.CultureInfo.CurrentCulture.Calendar"/>
/// </summary>
public Clock(bool shouldDispose = true)
: this(System.DateTimeOffset.Now.Offset, System.Globalization.CultureInfo.CurrentCulture.Calendar, shouldDispose)
{
try { if (false == GC && System.Runtime.GCSettings.LatencyMode != System.Runtime.GCLatencyMode.NoGCRegion) GC = System.GC.TryStartNoGCRegion(0); }
catch { }
finally
{
System.Threading.Thread.BeginCriticalRegion();
//Sample the TickCount
long ticksStart = System.Environment.TickCount,
ticksEnd;
//Continually sample the TickCount. while the value has not changed increment InstructionsPerClockUpdate
while ((ticksEnd = System.Environment.TickCount) == ticksStart) ++InstructionsPerClockUpdate; //+= 4; Read,Assign,Compare,Increment
//How many ticks occur per update of TickCount
TicksPerUpdate = ticksEnd - ticksStart;
System.Threading.Thread.EndCriticalRegion();
}
}
/// <summary>
/// Constructs a new clock using the given TimeZone offset and Calendar system
/// </summary>
/// <param name="timeZoneOffset"></param>
/// <param name="calendar"></param>
/// <param name="shouldDispose">Indicates if the instace should be diposed when Dispose is called.</param>
public Clock(System.TimeSpan timeZoneOffset, System.Globalization.Calendar calendar, bool shouldDispose = true)
{
//Allow disposal
ShouldDispose = shouldDispose;
Calendar = System.Globalization.CultureInfo.CurrentCulture.Calendar;
Created = new System.DateTimeOffset(System.DateTime.Now, timeZoneOffset);
}
#endregion
#region Overrides
public override void Dispose()
{
if (false == ShouldDispose) return;
base.Dispose();
try
{
if (System.Runtime.GCSettings.LatencyMode == System.Runtime.GCLatencyMode.NoGCRegion)
{
System.GC.EndNoGCRegion();
GC = false;
}
}
catch { }
}
#endregion
//Methods or statics for OperationCountToTimeSpan? (Estimate)
public void NanoSleep(int nanos)
{
Clock.NanoSleep((long)nanos);
}
public static void NanoSleep(long nanos)
{
System.Threading.Thread.BeginCriticalRegion();
NanoSleep(ref nanos);
System.Threading.Thread.EndCriticalRegion();
}
static void NanoSleep(ref long nanos)
{
try
{
unchecked
{
while (Common.Binary.Clamp(--nanos, 0, 1) >= 2)
{
/* if(--nanos % 2 == 0) */
NanoSleep(long.MinValue); //nanos -= 1 + (ops / (ulong)AverageOperationsPerTick);// *10;
}
}
}
catch
{
return;
}
}
}
}
Once you have some type of layman clock implementation you advance to something like a Timer
/// <summary>
/// Provides a Timer implementation which can be used across all platforms and does not rely on the existing Timer implementation.
/// </summary>
public class Timer : Common.BaseDisposable
{
readonly System.Threading.Thread m_Counter; // m_Consumer, m_Producer
internal System.TimeSpan m_Frequency;
internal ulong m_Ops = 0, m_Ticks = 0;
bool m_Enabled;
internal System.DateTimeOffset m_Started;
public delegate void TickEvent(ref long ticks);
public event TickEvent Tick;
public bool Enabled { get { return m_Enabled; } set { m_Enabled = value; } }
public System.TimeSpan Frequency { get { return m_Frequency; } }
internal ulong m_Bias;
//
//Could just use a single int, 32 bits is more than enough.
//uint m_Flags;
//
readonly internal Clock m_Clock = new Clock();
readonly internal System.Collections.Generic.Queue<long> Producer;
void Count()
{
System.Threading.Thread Event = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
{
System.Threading.Thread.BeginCriticalRegion();
long sample;
AfterSample:
try
{
Top:
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Highest;
while (m_Enabled && Producer.Count >= 1)
{
sample = Producer.Dequeue();
Tick(ref sample);
}
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest;
if (false == m_Enabled) return;
while (m_Enabled && Producer.Count == 0) if(m_Counter.IsAlive) m_Counter.Join(0); //++m_Ops;
goto Top;
}
catch { if (false == m_Enabled) return; goto AfterSample; }
finally { System.Threading.Thread.EndCriticalRegion(); }
}))
{
IsBackground = false,
Priority = System.Threading.ThreadPriority.AboveNormal
};
Event.TrySetApartmentState(System.Threading.ApartmentState.MTA);
Event.Start();
Approximate:
ulong approximate = (ulong)Common.Binary.Clamp((m_Clock.AverageOperationsPerTick / (Frequency.Ticks + 1)), 1, ulong.MaxValue);
try
{
m_Started = m_Clock.Now;
System.Threading.Thread.BeginCriticalRegion();
unchecked
{
Start:
if (IsDisposed) return;
switch (++m_Ops)
{
default:
{
if (m_Bias + ++m_Ops >= approximate)
{
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Highest;
Producer.Enqueue((long)m_Ticks++);
ulong x = ++m_Ops / approximate;
while (1 > --x /*&& Producer.Count <= m_Frequency.Ticks*/) Producer.Enqueue((long)++m_Ticks);
m_Ops = (++m_Ops * m_Ticks) - (m_Bias = ++m_Ops / approximate);
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest;
}
if(Event != null) Event.Join(m_Frequency);
goto Start;
}
}
}
}
catch (System.Threading.ThreadAbortException) { if (m_Enabled) goto Approximate; System.Threading.Thread.ResetAbort(); }
catch (System.OutOfMemoryException) { if ((ulong)Producer.Count > approximate) Producer.Clear(); if (m_Enabled) goto Approximate; }
catch { if (m_Enabled) goto Approximate; }
finally
{
Event = null;
System.Threading.Thread.EndCriticalRegion();
}
}
public Timer(System.TimeSpan frequency)
{
Producer = new System.Collections.Generic.Queue<long>((int)(m_Frequency = frequency).Ticks * 10);
m_Counter = new System.Threading.Thread(new System.Threading.ThreadStart(Count))
{
IsBackground = false,
Priority = System.Threading.ThreadPriority.AboveNormal
};
m_Counter.TrySetApartmentState(System.Threading.ApartmentState.MTA);
Tick = delegate { m_Ops += 1 + m_Bias; };
}
public void Start()
{
if (m_Enabled) return;
m_Enabled = true;
m_Counter.Start();
var p = System.Threading.Thread.CurrentThread.Priority;
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest;
while (m_Ops == 0) m_Counter.Join(0); //m_Clock.NanoSleep(0);
System.Threading.Thread.CurrentThread.Priority = p;
}
public void Stop()
{
m_Enabled = false;
}
void Change(System.TimeSpan interval, System.TimeSpan dueTime)
{
m_Enabled = false;
m_Frequency = interval;
m_Enabled = true;
}
delegate void ElapsedEvent(object sender, object args);
public override void Dispose()
{
if (IsDisposed) return;
base.Dispose();
Stop();
try { m_Counter.Abort(m_Frequency); }
catch (System.Threading.ThreadAbortException) { System.Threading.Thread.ResetAbort(); }
catch { }
Tick = null;
//Producer.Clear();
}
}
Then you can really replicate some logic using something like
/// <summary>
/// Provides a completely managed implementation of <see cref="System.Diagnostics.Stopwatch"/> which expresses time in the same units as <see cref="System.TimeSpan"/>.
/// </summary>
public class Stopwatch : Common.BaseDisposable
{
internal Timer Timer;
long Units;
public bool Enabled { get { return Timer != null && Timer.Enabled; } }
public double ElapsedMicroseconds { get { return Units * Media.Common.Extensions.TimeSpan.TimeSpanExtensions.TotalMicroseconds(Timer.Frequency); } }
public double ElapsedMilliseconds { get { return Units * Timer.Frequency.TotalMilliseconds; } }
public double ElapsedSeconds { get { return Units * Timer.Frequency.TotalSeconds; } }
//public System.TimeSpan Elapsed { get { return System.TimeSpan.FromMilliseconds(ElapsedMilliseconds / System.TimeSpan.TicksPerMillisecond); } }
public System.TimeSpan Elapsed
{
get
{
switch (Units)
{
case 0: return System.TimeSpan.Zero;
default:
{
System.TimeSpan taken = System.DateTime.UtcNow - Timer.m_Started;
return taken.Add(new System.TimeSpan(Units * Timer.Frequency.Ticks));
//System.TimeSpan additional = new System.TimeSpan(Media.Common.Extensions.Math.MathExtensions.Clamp(Units, 0, Timer.Frequency.Ticks));
//return taken.Add(additional);
}
}
//////The maximum amount of times the timer can elapse in the given frequency
////double maxCount = (taken.TotalMilliseconds / Timer.Frequency.TotalMilliseconds) / ElapsedMilliseconds;
////if (Units > maxCount)
////{
//// //How many more times the event was fired than needed
//// double overage = (maxCount - Units);
//// additional = new System.TimeSpan(System.Convert.ToInt64(Media.Common.Extensions.Math.MathExtensions.Clamp(Units, overage, maxCount)));
//// //return taken.Add(new System.TimeSpan((long)Media.Common.Extensions.Math.MathExtensions.Clamp(Units, overage, maxCount)));
////}
//////return taken.Add(new System.TimeSpan(Units));
}
}
public void Start()
{
if (Enabled) return;
Units = 0;
//Create a Timer that will elapse every OneTick //`OneMicrosecond`
Timer = new Timer(Media.Common.Extensions.TimeSpan.TimeSpanExtensions.OneTick);
//Handle the event by incrementing count
Timer.Tick += Count;
Timer.Start();
}
public void Stop()
{
if (false == Enabled) return;
Timer.Stop();
Timer.Dispose();
}
void Count(ref long count) { ++Units; }
}
Finally, create something semi useful e.g. a Bus and then perhaps a virtual screen to emit data to the bus...
public abstract class Bus : Common.CommonDisposable
{
public readonly Timer Clock = new Timer(Common.Extensions.TimeSpan.TimeSpanExtensions.OneTick);
public Bus() : base(false) { Clock.Start(); }
}
public class ClockedBus : Bus
{
long FrequencyHz, Maximum, End;
readonly Queue<byte[]> Input = new Queue<byte[]>(), Output = new Queue<byte[]>();
readonly double m_Bias;
public ClockedBus(long frequencyHz, double bias = 1.5)
{
m_Bias = bias;
cache = Clock.m_Clock.InstructionsPerClockUpdate / 1000;
SetFrequency(frequencyHz);
Clock.Tick += Clock_Tick;
Clock.Start();
}
public void SetFrequency(long frequencyHz)
{
FrequencyHz = frequencyHz;
//Clock.m_Frequency = new TimeSpan(Clock.m_Clock.InstructionsPerClockUpdate / 1000);
//Maximum = System.TimeSpan.TicksPerSecond / Clock.m_Clock.InstructionsPerClockUpdate;
//Maximum = Clock.m_Clock.InstructionsPerClockUpdate / System.TimeSpan.TicksPerSecond;
Maximum = cache / (cache / FrequencyHz);
Maximum *= System.TimeSpan.TicksPerSecond;
Maximum = (cache / FrequencyHz);
End = Maximum * 2;
Clock.m_Frequency = new TimeSpan(Maximum);
if (cache < frequencyHz * m_Bias) throw new Exception("Cannot obtain stable clock");
Clock.Producer.Clear();
}
public override void Dispose()
{
ShouldDispose = true;
Clock.Tick -= Clock_Tick;
Clock.Stop();
Clock.Dispose();
base.Dispose();
}
~ClockedBus() { Dispose(); }
long sample = 0, steps = 0, count = 0, avg = 0, cache = 1;
void Clock_Tick(ref long ticks)
{
if (ShouldDispose == false && false == IsDisposed)
{
//Console.WriteLine("#ops=>" + Clock.m_Ops + " #ticks=>" + Clock.m_Ticks + " #Lticks=>" + ticks + "#=>" + Clock.m_Clock.Now.TimeOfDay + "#=>" + (Clock.m_Clock.Now - Clock.m_Clock.Created));
steps = sample;
sample = ticks;
++count;
System.ConsoleColor f = System.Console.ForegroundColor;
if (count <= Maximum)
{
System.Console.BackgroundColor = ConsoleColor.Yellow;
System.Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("count=> " + count + "#=>" + Clock.m_Clock.Now.TimeOfDay + "#=>" + (Clock.m_Clock.Now - Clock.m_Clock.Created) + " - " + DateTime.UtcNow.ToString("MM/dd/yyyy hh:mm:ss.ffffff tt"));
avg = Maximum / count;
if (Clock.m_Clock.InstructionsPerClockUpdate / count > Maximum)
{
System.Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("---- Over InstructionsPerClockUpdate ----" + FrequencyHz);
}
}
else if (count >= End)
{
System.Console.BackgroundColor = ConsoleColor.Black;
System.Console.ForegroundColor = ConsoleColor.Blue;
avg = Maximum / count;
Console.WriteLine("avg=> " + avg + "#=>" + FrequencyHz);
count = 0;
}
}
}
//Read, Write at Frequency
}
public class VirtualScreen
{
TimeSpan RefreshRate;
bool VerticalSync;
int Width, Height;
Common.MemorySegment DisplayMemory, BackBuffer, DisplayBuffer;
}
Here is how I tested the StopWatch
internal class StopWatchTests
{
public void TestForOneMicrosecond()
{
System.Collections.Generic.List<System.Tuple<bool, System.TimeSpan, System.TimeSpan>> l = new System.Collections.Generic.List<System.Tuple<bool, System.TimeSpan, System.TimeSpan>>();
//Create a Timer that will elapse every `OneMicrosecond`
for (int i = 0; i <= 250; ++i) using (Media.Concepts.Classes.Stopwatch sw = new Media.Concepts.Classes.Stopwatch())
{
var started = System.DateTime.UtcNow;
System.Console.WriteLine("Started: " + started.ToString("MM/dd/yyyy hh:mm:ss.ffffff tt"));
//Define some amount of time
System.TimeSpan sleepTime = Media.Common.Extensions.TimeSpan.TimeSpanExtensions.OneMicrosecond;
System.Diagnostics.Stopwatch testSw = new System.Diagnostics.Stopwatch();
//Start
testSw.Start();
//Start
sw.Start();
while (testSw.Elapsed.Ticks < sleepTime.Ticks - (Common.Extensions.TimeSpan.TimeSpanExtensions.OneTick + Common.Extensions.TimeSpan.TimeSpanExtensions.OneTick).Ticks)
sw.Timer.m_Clock.NanoSleep(0); //System.Threading.Thread.SpinWait(0);
//Sleep the desired amount
//System.Threading.Thread.Sleep(sleepTime);
//Stop
testSw.Stop();
//Stop
sw.Stop();
var finished = System.DateTime.UtcNow;
var taken = finished - started;
var cc = System.Console.ForegroundColor;
System.Console.WriteLine("Finished: " + finished.ToString("MM/dd/yyyy hh:mm:ss.ffffff tt"));
System.Console.WriteLine("Sleep Time: " + sleepTime.ToString());
System.Console.WriteLine("Real Taken Total: " + taken.ToString());
if (taken > sleepTime)
{
System.Console.ForegroundColor = System.ConsoleColor.Red;
System.Console.WriteLine("Missed by: " + (taken - sleepTime));
}
else
{
System.Console.ForegroundColor = System.ConsoleColor.Green;
System.Console.WriteLine("Still have: " + (sleepTime - taken));
}
System.Console.ForegroundColor = cc;
System.Console.WriteLine("Real Taken msec Total: " + taken.TotalMilliseconds.ToString());
System.Console.WriteLine("Real Taken sec Total: " + taken.TotalSeconds.ToString());
System.Console.WriteLine("Real Taken μs Total: " + Media.Common.Extensions.TimeSpan.TimeSpanExtensions.TotalMicroseconds(taken).ToString());
System.Console.WriteLine("Managed Taken Total: " + sw.Elapsed.ToString());
System.Console.WriteLine("Diagnostic Taken Total: " + testSw.Elapsed.ToString());
System.Console.WriteLine("Diagnostic Elapsed Seconds Total: " + ((testSw.ElapsedTicks / (double)System.Diagnostics.Stopwatch.Frequency)));
//Write the rough amount of time taken in micro seconds
System.Console.WriteLine("Managed Time Estimated Taken: " + sw.ElapsedMicroseconds + "μs");
//Write the rough amount of time taken in micro seconds
System.Console.WriteLine("Diagnostic Time Estimated Taken: " + Media.Common.Extensions.TimeSpan.TimeSpanExtensions.TotalMicroseconds(testSw.Elapsed) + "μs");
System.Console.WriteLine("Managed Time Estimated Taken: " + sw.ElapsedMilliseconds);
System.Console.WriteLine("Diagnostic Time Estimated Taken: " + testSw.ElapsedMilliseconds);
System.Console.WriteLine("Managed Time Estimated Taken: " + sw.ElapsedSeconds);
System.Console.WriteLine("Diagnostic Time Estimated Taken: " + testSw.Elapsed.TotalSeconds);
if (sw.Elapsed < testSw.Elapsed)
{
System.Console.WriteLine("Faster than Diagnostic StopWatch");
l.Add(new System.Tuple<bool, System.TimeSpan, System.TimeSpan>(true, sw.Elapsed, testSw.Elapsed));
}
else if (sw.Elapsed > testSw.Elapsed)
{
System.Console.WriteLine("Slower than Diagnostic StopWatch");
l.Add(new System.Tuple<bool, System.TimeSpan, System.TimeSpan>(false, sw.Elapsed, testSw.Elapsed));
}
else
{
System.Console.WriteLine("Equal to Diagnostic StopWatch");
l.Add(new System.Tuple<bool, System.TimeSpan, System.TimeSpan>(true, sw.Elapsed, testSw.Elapsed));
}
}
int w = 0, f = 0;
var cc2 = System.Console.ForegroundColor;
foreach (var t in l)
{
if (t.Item1)
{
System.Console.ForegroundColor = System.ConsoleColor.Green;
++w; System.Console.WriteLine("Faster than Diagnostic StopWatch by: " + (t.Item3 - t.Item2));
}
else
{
System.Console.ForegroundColor = System.ConsoleColor.Red;
++f; System.Console.WriteLine("Slower than Diagnostic StopWatch by: " + (t.Item2 - t.Item3));
}
}
System.Console.ForegroundColor = System.ConsoleColor.Green;
System.Console.WriteLine("Wins = " + w);
System.Console.ForegroundColor = System.ConsoleColor.Red;
System.Console.WriteLine("Loss = " + f);
System.Console.ForegroundColor = cc2;
}
}

schedule a task after a delay in executor service

I want a task to be executed after a delay of 3 seconds and my one task takes 2 seconds to finish.
The output i am getting is showing interval of 5 seconds
Note:The Student class implements Callable interface
I have the following queries
Why there is delay of 5 seconds coming.How can make a delay of 3
seconds Why are thread 1 is showed in second execution ,it should be
thread two
The output i am getting is
The time is : Sat Nov 26 15:08:02 IST 2016
Doing a task during : prerna - Time - Sat Nov 26 15:08:06 IST 2016
pool-1-thread-1 Helloprerna
Doing a task during : abc - Time - Sat Nov 26 15:08:11 IST 2016
pool-1-thread-1 Helloabc
Doing a task during : def - Time - Sat Nov 26 15:08:16 IST 2016
pool-1-thread-2 Hellodef
Doing a task during : xyz - Time - Sat Nov 26 15:08:21 IST 2016
pool-1-thread-1 Helloxyz
Doing a task during : ritu - Time - Sat Nov 26 15:08:26 IST 2016
pool-1-thread-3 Helloritu
Doing a task during : babita - Time - Sat Nov 26 15:08:31 IST 2016
pool-1-thread-2 Hellobabita
The code:
private String display(String name2) {
try {
// System.out.println(Thread.currentThread().getName());
name2=Thread.currentThread().getName()+" Hello"+ name;
System.out.println("Doing a task during : " + name + " - Time - " + new Date());
Thread.sleep(000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return name2;
}
#Override
public String call() throws Exception {
// TODO Auto-generated method stub
if (name == "archana") {
throw new Exception();
}
/*} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}finally{
return "error";
}*/
return display(name);
}
public class ExecutorScheduleDemo {
public static void main(String args[]) throws InterruptedException{
ScheduledExecutorService executor= Executors.newScheduledThreadPool(5);
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("prerna"));
list.add(new Student("abc"));
//list.add(new Student("archana"));
list.add(new Student("def"));
list.add(new Student("xyz"));
list.add(new Student("ritu"));
list.add(new Student("babita"));
System.out.println("The time is : " + new Date());
List<Future<String>> resultList= new ArrayList<Future<String>>();
for(Student s:list){
Future<String> f=executor.schedule(s, 3, TimeUnit.SECONDS);
try {
System.out.println(f.get());
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Use scheduleAtFixedRate(Runnable, long initialDelay, long period, TimeUnit timeunit) instead of schedule(Runnable task, long delay, TimeUnit timeunit).
scheduleAtFixedRate (Runnable, long initialDelay, long period,
TimeUnit timeunit)
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
next execution.
To complete eeedev's answer, since your object seems to be a Callable:
You can simply create a new FutureTask by passing your Callable to the constructor, as described in the oracle docs
Note that the FutureTask's type parameter must be the same as the Callable's.
Example:
class Main {
public static void main(String[] args) {
Foo foo = new Foo();
FutureTask<String> fooFutureTask = new FutureTask<>(foo);
}
}
class Foo implements Callable<String> {
#Override
public String call() throws Exception {
return "Calling";
}
}
You can then schedule your newly created FutureTask for execution as described by eeedev.

Categories

Resources