Need help a bit, please. How to make it work in the following order: check value of an i, run Timer for it, ONLY when that timer is finished, do i++? For now two timers run at the same time. Tried to declare boolean isRunning, but did not help.
for(int i=0;i<pcArray.length;i++){
if(pcArray[i]==1){
blinkGreen.start(); }
else if(pcArray[i]==2){
blinkRed.start();
}
}
First add a boolean variable in blinkGreen and also in blinkRed Timer like this,
In BlinkGreen:
boolean isRunningGreen = false;
Timer blinkGreen = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
// do stuff
isRunningGreen = true;//This statement must be placed at the end/bottom of this method
}
};
In BlinkRed:
boolean isRunningRed = false;
Timer blinkRed = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
// do stuff
isRunningRed = true;//This statement must be placed at the end/bottom of this method
}
};
Now try this:
for(int i=0;i<pcArray.length;i++){
if(pcArray[i]==1){
blinkGreen.start();
while(!isRunningGreen){}//waiting until the task is completed
} else if(pcArray[i]==2){
blinkRed.start();
while(!isRunningRed){}//waiting until the task is completed
}
}
Related
It runs with processing time and using a broadcast state.
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);
BroadcastStream<List<TableOperations>> broadcastOperationsState = env
.addSource(new LoadCassandraOperations(10000L, cassandraHost, cassandraPort)).broadcast(descriptor);
SingleOutputStreamOperator<InternalVariableValue> stream =
env.addSource(new SourceMillisInternalVariableValue(5000L));
SingleOutputStreamOperator<InternalVariableOperation> streamProcessed =
stream
.keyBy(InternalVariableValue::getUuid)
.connect(broadcastOperationsState)
.process(new AddOperationInfo())
;
streamProcessed.print();
SourceMillisIntervalVariableValues create a event every 5s . The events are stored in a static collection. The run method looks like :
public class SourceMillisInternalVariableValue extends RichSourceFunction<InternalVariableValue>{
private boolean running;
long millis;
public SourceMillisInternalVariableValue(long millis) {
super();
this.millis = millis;
}
#Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
running = true;
}
#Override
public void cancel() {
running = false;
}
#Override
public void run(SourceContext<InternalVariableValue> ctx) throws Exception {
//Espera inicial
Thread.sleep(1500);
PojoVariableValues[] pojoData =
new PojoVariableValues[]{
new PojoVariableValues("id1", "1"),
new PojoVariableValues("id2", "2"),
....
....
new PojoVariableValues("id21", "21")
};
int cont = 0;
while (cont<pojoData.length) {
System.out.println("Iteration "+cont+" "+pojoData.length);
ctx.collect(generateVar(pojoData[0+cont].getUUID(), pojoData[0+cont].getValue()));
ctx.collect(generateVar(pojoData[1+cont].getUUID(), pojoData[1+cont].getValue()));
ctx.collect(generateVar(pojoData[2+cont].getUUID(), pojoData[2+cont].getValue()));
cont = cont +3;
Thread.sleep(millis);
}
}
private InternalVariableValue generateVar(String uuid, String value)
{
return InternalVariableValueMessage.InternalVariableValue.newBuilder()
.setUuid(uuid)
.setTimestamp(new Date().getTime()).setValue(value).setKeyspace("nest").build();
}
class PojoVariableValues {
private String UUID;
private String Value;
public PojoVariableValues(String uUID, String value) {
super();
UUID = uUID;
Value = value;
}
public String getUUID() {
return UUID;
}
public void setUUID(String uUID) {
UUID = uUID;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
}
}
}
LoadCassandraOperations emits events every 10 seconds. It works fine.
When I run this code, SourceMillisIntervalVariableValues stops in the first iteration, emiting only three events. If I comment the process function, both sources works properly, but if I run the process , the source is cancel...
I spect than the source emits all events ( 21 exactly ) , and all of them are processing in the aggregate function. If I run this code, the while loop in the sources only complete one iteration.
Any idea ?
Thank youuu . cheers
EDIT:
Important. This code is for explore the processint time and broadcast feature. I know that I'm not using the best practices in the sources. Thanks
EDIT 2:
The problem starts when I try to run the process function.
Solved !!
The problem was that I try to run it using a TestContainer and I can't watch any logs.
I ran it with a simple main method and I can see some code errors ( like the commented in the comments. Tnks !!! ).
I want to send notifications after every 30 seconds. I have scheduled my task using TimerTask but it is not working. Why is it so? My Searcher is given below:
#Override
public Result search(Query query, Execution execution) {
// pass it down the chain to get a result
Result result = execution.search(query);
execution.fill(result);
//the Date and time at which you want to execute
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = dateFormatter.parse("2018-10-17 16:20:00");
} catch (ParseException e) {
e.printStackTrace();
}
//Now create the time and schedule it
Timer timer = new Timer();
assert date != null;
timer.schedule(new TimerTask() {
#Override
public void run() {
sendNotification();
}
}, date, 30000);
// return the result up the chain
return result;
}
The search() method is invoked on a per request basis and you are creating a new Timer instance per request which is garbage collected away by the Java VM some time after the search method returns as there are no references to it.
I am trying to make a game where you can only enter words for 10 seconds. I tried to create a multithread solution but it doesn't work properly.
class timer extends Thread{//thread
public void run(){
for(int i=10;i>=0;i--){
System.out.print(i+" ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Main method:
timer t=new timer();
t.start();
while () {//not sure what to put in my while statement
System.out.print("Guess a word on the board! ");
if(test.CheckGame(scan.next())==true){
System.out.print("Good job! ");
}
else
System.out.print("Guess again! ");
}
essentially, after the thread goes for 10 seconds and terminates,I want it to return a break statement so the program leaves the while loop. Any suggestions?
Change your code to this
timer t=new timer();
t.start();
while (t.isAlive()) {//not sure what to put in my while statement
System.out.print("Guess a word on the board! ");
if(test.CheckGame(scan.next())==true){
System.out.print("Good job! ");
}
else
System.out.print("Guess again! ");
}
Once the run function exits, t.isAlive will be false. You may also need to pass the timer object around and check the isAlive() of the object, depending on how CheckGame works. This is so that the input cannot be put in after the 10 seconds for an indefinite period of time.
Here is a simple Demo that would let you to know how to use java.util.Timer .
import java.util.Timer;
import java.util.TimerTask;
import java.util.Scanner;
class Tester
{
static long i = 0;
public static void main(String[] args) throws Exception
{
Scanner scanner = new Scanner(System.in);
System.out.println("You have only 10 seconds to find the result");
System.out.println("What is the value of : 111111 X 111111 ");
Timer timer = new Timer("Timer");
timer.schedule(new TimerTask()
{
public void run()
{
if (i == 12345654321L)
{
System.out.println("Congrats!! you guessed the write answer :)");
}
else
{
System.out.println("Sorry Time is over. You couldn't guess the correct answer.");
}
System.exit(0);
}
},10 * 1000 , 1);
while (true)
{
i = scanner.nextLong();
if ( i == 12345654321L)
{
System.out.println("Congrats!! you guessed the write answer :)");
System.exit(0);
}
else
{
System.out.println("Try next guess :");
}
}
}
}
EDIT
Since I don't have your all code so I am posting here the solution for your answer on my basic assumption. Don't use Thread. Instead use java.util.Timer. Your code would look as follows:
static String input=" ";//created a static variable input to take input
public static void main(String st[])
{
Timer timer = new Timer("Timer");
timer.schedule(new TimerTask()
{
public void run()
{
if (test.CheckGame(input))
{
System.out.println("Congrats!! you guessed the write answer :)");
}
else
{
System.out.println("Sorry Time is over. You couldn't guess the correct answer.");
}
System.exit(0);
}
},10 * 1000 , 1);//waits for 10 seconds
while (true)
{
System.out.print("Guess a word on the board! ");
input = scan.next();
if(test.CheckGame(input))
{
System.out.print("Good job! ");
System.exit(0);
}
else
{
System.out.println("Bad Guess. Try again ");
}
}
}
You could have a shared boolean where your thread and main share in a synchronized fashion.
The timer could be as follows;
class timer extends Thread{//thread
private Object lock = new Object(); // a lock used by both your thread and main to access stop boolean
private boolean stop = false;
public void setStop() // your thread calls this method in order to set stop
{
synchronized(lock) {
stop = true;
}
}
public boolean getStop() // main calls this to see if thread told main to stop.
{
boolean _stop;
synchronized(lock) {
_stop = stop;
}
return _stop;
}
public void run(){
for(int i=10;i>=0;i--){
System.out.print(i+" ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setStop();
}
}
}
Your main could be as follows:
timer t=new timer();
t.start();
while (!t.getStop()) {// calls getStop to see if other thread told main to stop
System.out.print("Guess a word on the board! ");
if(test.CheckGame(scan.next())==true){
System.out.print("Good job! ");
}
else
System.out.print("Guess again! ");
}
t.join(); // to make sure main terminates after the termination of other thread
I would like to catch an observable thats loading an add and have it show after a few seconds. Im calling this is multiple places but in one particular place i'd like it to only run after a few seconds have elapsed. Here is the method i have that returns an observable:
private Observable fullScreenAdObservable(){
// Create the interstitial.
return Observable.create(new Observable.OnSubscribe<Object>() {
#Override
public void call(Subscriber<? super Object> subscriber) {
interstitial = new InterstitialAd(main.this);
interstitial.setAdUnitId(admob_publisherID);
// Create ad request.
AdRequest adRequest = new AdRequest.Builder().build();
// Begin loading your interstitial.
interstitial.loadAd(adRequest);
interstitial.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
interstitial.show();
}
});
}
});
}
then to subscribe i do this but the timer one fails:
fullScreenAdObservable().subscribe();//this works
fullScreenAdObservable().timer(0,3, TimeUnit.SECONDS).subscribe(); //this fails to react,why ?
I want the timer to run the observerable after 3 seconds but it wont, why ?
There seems to be some scheduling issue when using delay and timer. So i had to explicity tell what thread i want to subscribe on BEFORE calling the delaySubscription or timer. Also modified the subscriber to listen for onNext so i can pass the subscriber a ad. Then i actually showed the ad in the onNext (as its triggered after the delay is elapsed.
private Observable fullScreenAdObservable(){
// Create the interstitial.
return Observable.create(new Observable.OnSubscribe<Object>() {
#Override
public void call(final Subscriber<? super Object> subscriber) {
interstitial = new InterstitialAd(main.this);
interstitial.setAdUnitId(admob_publisherID);
// Create ad request.
AdRequest adRequest = new AdRequest.Builder().build();
// Begin loading your interstitial.
interstitial.loadAd(adRequest);
interstitial.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
//emit a loaded ad
subscriber.onNext(interstitial);
}
});
}
});
}
//and to call it :
fullScreenAdObservable().subscribeOn(AndroidSchedulers.mainThread()).
delaySubscription(13, TimeUnit.SECONDS).subscribe(new Action1<InterstitialAd>() {
#Override
public void call(InterstitialAd ad) {
ad.show();
}
});
I am using a Timer to run an event periodically on a reasonably long interval (2 minutes). This is working fine. However I would like the event to fire immediately when the timer is created (instead of waiting 2 minutes).
Note that I can't do this just by calling the method, since it takes some time to run and would block the application. I need the timer to fire as normal and run the event in a separate thread.
The best way I can think of doing this at the moment is subclassing the timer and creating a TriggerManually method that would do something like this:
Turn auto reset off
Set the interval to 1ms
Enable the timer
This would trigger the elapsed event straight away, and I could put all the settings back to normal.
Seems a bit roundabout though. Is there a better way to do it?
Couldn't you just call your event handler for the elapsed event manually?
Even if you were expecting it to execute on a thread pool thread, you could invoke it.
class Blah
{
private Timer mTimer;
public Blah()
{
mTimer = new Timer(120000);
ElapsedEventHandler handler = new ElapsedEventHandler(Timer_Elapsed);
mTimer.Elapsed += handler;
mTimer.Enabled = true;
//Manually execute the event handler on a threadpool thread.
handler.BeginInvoke(this, null, new AsyncCallback(Timer_ElapsedCallback), handler);
}
private static void Timer_Elapsed(object source, ElapsedEventArgs e)
{
//Do stuff...
}
private void Timer_ElapsedCallback(IAsyncResult result)
{
ElapsedEventHandler handler = result.AsyncState as ElapsedEventHandler;
if (handler != null)
{
handler.EndInvoke(result);
}
}
}
I liked Rob Cooke's answer, so I built a small EagerTimer class that subclasses System.Timers.Timer and adds this functionality. (With hints from these articles)
I know I could use System.Threading.Timer instead, but this is simple and works well in my application.
EagerTimer
/// <summary>
// EagerTimer is a simple wrapper around System.Timers.Timer that
// provides "set up and immediately execute" functionality by adding a
// new AutoStart property, and also provides the ability to manually
// raise the Elapsed event with RaiseElapsed.
/// </summary>
public class EagerTimer : Timer
{
public EagerTimer()
: base() { }
public EagerTimer(double interval)
: base(interval) { }
// Need to hide this so we can use Elapsed.Invoke below
// (otherwise the compiler complains)
private event ElapsedEventHandler _elapsedHandler;
public new event ElapsedEventHandler Elapsed
{
add { _elapsedHandler += value; base.Elapsed += value; }
remove { _elapsedHandler -= value; base.Elapsed -= value; }
}
public new void Start()
{
// If AutoStart is enabled, we need to invoke the timer event manually
if (AutoStart)
{
this._elapsedHandler.BeginInvoke(this, null, new AsyncCallback(AutoStartCallback), _elapsedHandler); // fire immediately
}
// Proceed as normal
base.Start();
}
private void AutoStartCallback(IAsyncResult result)
{
ElapsedEventHandler handler = result.AsyncState as ElapsedEventHandler;
if (handler != null) handler.EndInvoke(result);
}
// Summary:
// Gets or sets a value indicating whether the EagerTimer should raise
// the System.Timers.Timer.Elapsed event immediately when Start() is called,
// or only after the first time it elapses. If AutoStart is false, EagerTimer behaves
// identically to System.Timers.Timer.
//
// Returns:
// true if the EagerTimer should raise the System.Timers.Timer.Elapsed
// event immediately when Start() is called; false if it should raise the System.Timers.Timer.Elapsed
// event only after the first time the interval elapses. The default is true.
[Category("Behavior")]
[DefaultValue(true)]
[TimersDescription("TimerAutoStart")]
public bool AutoStart { get; set; }
/// <summary>
/// Manually raises the Elapsed event of the System.Timers.Timer.
/// </summary>
public void RaiseElapsed()
{
if (_elapsedHandler != null)
_elapsedHandler(this, null);
}
}
Unit Tests
[TestClass]
public class Objects_EagerTimer_Tests
{
private const int TimerInterval = 10; // ms
private List<DateTime> _timerFires = new List<DateTime>();
private DateTime _testStart;
[TestInitialize]
public void TestSetup()
{
_timerFires.Clear();
_testStart = DateTime.Now;
}
[TestMethod]
public void Objects_EagerTimer_WithAutoStartDisabled()
{
// EagerTimer should behave as a normal System.Timers.Timer object
var timer = new EagerTimer(TimerInterval);
timer.AutoReset = false;
timer.Elapsed += timerElapsed;
timer.Start();
// Wait (not enough time for first interval)
Thread.Sleep(5);
Assert.IsFalse(_timerFires.Any());
// Wait a little longer
Thread.Sleep(TimerInterval);
Assert.AreEqual(1, _timerFires.Count);
}
[TestMethod]
public void Objects_EagerTimer_WithAutoStartEnabled()
{
// EagerTimer should fire immediately on Start()
var timer = new EagerTimer(TimerInterval);
timer.AutoReset = false;
timer.AutoStart = true;
timer.Elapsed += timerElapsed;
timer.Start();
// Wait (not enough time for first interval)
Thread.Sleep(5);
Assert.IsTrue(_timerFires.Any());
// Wait a little longer, now it will have fired twice
Thread.Sleep(TimerInterval);
Assert.AreEqual(2, _timerFires.Count);
}
[TestMethod]
public void Objects_EagerTimer_WhenRaisingManually()
{
// EagerTimer should fire immediately on Start()
var timer = new EagerTimer(TimerInterval);
timer.AutoReset = false;
timer.AutoStart = false;
timer.Elapsed += timerElapsed;
Assert.IsFalse(_timerFires.Any());
timer.RaiseElapsed();
Assert.IsTrue(_timerFires.Any());
}
private void timerElapsed(object sender, ElapsedEventArgs e) {
_timerFires.Add(DateTime.Now);
}
}
Could you use a System.Threading.Timer instead ?
It has a constructor that lets you choose the interval as well as the delay (which can be set to 0 to begin immediately).
http://msdn.microsoft.com/en-us/library/2x96zfy7.aspx