I am creating a new thread to check a folder for new files then sleeping for a defined period of time.
My preference would be to use the ScheduledExecutorService, however, I can't find any documentation to clarify if this waits for the currently running task to complete before starting a new one.
For example, in the following code;
Integer samplingInterval = 30;
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10);
executorService.scheduleAtFixedRate(new WatchAgent(agentInfo),
0,
samplingInterval,
TimeUnit.SECONDS);
If the run() of WatchAgent takes longer than 30 seconds, will a new agent be created before it finishes?
Secondly, if I create an instance of WatchAgent, can I keep using the same instance for each periodic run?
Per the javadoc of scheduleAtFixedRate:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
scheduleAtFixedRate by definition takes a single Runnable instance. There is no way for you to provide different instances for each invocation of run. So to answer your question, the same instance will always be used for each periodic run.
Try this test code below.
1) Yes, it seems to wait until run() is finished.
2) Yes, seems it is using the same instance's run method (the one you passed in when you called scheduleAtFixedRate; this makes perfect sense btw).
import java.util.Date;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test006 {
public static void main(String[] args) {
Object agentInfo = null;
Integer samplingInterval = 30;
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10);
executorService.scheduleAtFixedRate(new WatchAgent(agentInfo), 0, samplingInterval, TimeUnit.SECONDS);
}
}
class WatchAgent implements Runnable {
public WatchAgent(Object info){
}
public void run(){
try{
System.out.println("Running " + this.hashCode() + " - started on/at " + (new Date()));
Thread.sleep(60000);
System.out.println("Running " + this.hashCode() + " - finished on/at " + (new Date()));
}catch(Exception ex){
ex.printStackTrace();
}
}
}
Output:
Running 1322575120 - started on/at Mon Jul 08 19:58:41 IST 2019
Running 1322575120 - finished on/at Mon Jul 08 19:59:41 IST 2019
Running 1322575120 - started on/at Mon Jul 08 19:59:41 IST 2019
Running 1322575120 - finished on/at Mon Jul 08 20:00:41 IST 2019
Running 1322575120 - started on/at Mon Jul 08 20:00:41 IST 2019
...
Related
I am trying to update a large (~150,000 line) Java/Eclipse program from 2009 that has several threads, and communicates with a TCP-IP telescope. I wrote new code to do the communications, and that all works fine when separately tested. This is on a Mac - the original worked on Mac OSX 10.6 and nothing later - I'm writing this for current Mac OS 12.xx
In the overall program, there is a thread that receives mouse clicks from the GUI and initiates operation of a thread with runs the communications code. The communications thread stays alive, using parameters passed to it to determine which communication function to execute.
Here's some of the code:
class ActualTask {
ActualTask () {
// PRAA Dec 7 2021
System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
while (true) // this is true so we can keep reusing this task!
{
// PRAA Dec 7 2021
//System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
if (running)
{
// PRAA Dec 7 2021
System.out.println("Just before call to run() - What thread are we in? it's: "+ Thread.currentThread().getName());
run();
// PRAA Dec 7 2021
System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
running = false;
}
}
}
// ------------------------------------
void run()
{
done = false;
successful = true;
telescopeException = null;
// PRAA Dec 7 2021
System.out.println("In run() - thread is: "+ Thread.currentThread().getName());
try
{ // *** execute the telescope task ***
TelescopeGlobals.telescopeProgressTaskData.setBackgroundColor(Color.red); // red when active
telescopeTask.execute();
done = true;
TelescopeGlobals.telescopeProgressTaskData.setBackgroundColor(Color.white); // white when NOT active
}
catch (TelescopeException te)
{
// Clear progress bar before throwing up dialog
TelescopeGlobals.telescopeProgressTaskData.setBackgroundColor(Color.white); // white when NOT active
TelescopeGlobals.telescopeProgressTaskData.clear();
done = true;
successful = false;
telescopeException = te;
Reporting.selctiveAlert(te.getMessage() + "\n" + te.getWhereExceptionOccured());
TelescopeGlobals.telescopeProgressTaskData.setText1("Error: " + te.getMessage());
TelescopeGlobals.telescopeProgressTaskData.setText2("Where: " + te.getWhereExceptionOccured());
}
done = true;
}
}
When I am in "debug" mode, and I single-step through the communications code, things usually execute properly - however, when I hit "Run", things don't go so well -
the first call works ok
the second call appears to do nothing - that is, it doesn't seem to be executing, and none of my print statements print
subsequent calls only print an error message saying the previous task has not completed.
So I'm wondering - what is the difference between the "run" and "debug" modes - why would one work and the other behave differently - and
Does all of the "SwingWorker" stuff from 2009 still work?
Should creating the communications thread be done differently? It is just created once, as shown in the code snippet below:
// Static member above of HighLevelTaskWorker makes sure that one command is dispatched to the telescope at a time.
class HighLevelTaskWorker { // SwingWorker wrapper class
private lib.SwingWorker worker = null;
private boolean done;
private boolean successful;
private TelescopeException telescopeException;
private boolean running;
private TelescopeTask telescopeTask;
public HighLevelTaskWorker()
{
}
public void start(TelescopeTask telescopeTask) {
this.telescopeTask = telescopeTask;
// PRAA Dec 7 2021
System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
done = false;
successful = false;
telescopeException = null;
running = true;
if (worker == null) // no need to create this tread over and over again, think of all that Garbage Collecting and tread creation!
{
worker = new lib.SwingWorker() {
public Object construct() {
return new ActualTask();
}
};
worker.start();
}
}
Thanks so much for any help !!!
This is what I have in my Servlet.
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("Initializing...");
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.execute(new Runnable() {
public void run() {
System.out.println("Inside Thread!!!");
for(int i=1; i<5; i++){
System.out.println("Date: " + new Date());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
executorService.shutdown();
// Some more piece of code is there
}
What I am doing here:
I have created a separate thread where the date gets printed after 5 sec in the console.
What I want to do:
When I run this code, I get this output printed in the console:
Initializing...
Inside Thread!!!
Date : Sat Nov 01 15:57:57 GMT 2014
Date : Sat Nov 01 15:58:02 GMT 2014
Date : Sat Nov 01 15:58:07 GMT 2014
Date : Sat Nov 01 15:58:12 GMT 2014
I want the same set of messages to be printed in a jsp page in such a way that the Date gets printed in an interval of 5 sec (by sending multiple response to the browser whenever a Syetem.out.println() method is executed int he above code).
Reason for pushing message from server:
In the above example, I am printing simple messages in a loop. But in real scenario, there are some calculations, hence the messages will be available at different time frames (i.e. not after every 5 sec, some messages will be available in quick time while the other messages might take some more time). Hence if I push from the server, then I can push the messages whenever it is available.
Unable to understand:
I am not sure how to send multiple response to the browser from a separate thread (i.e. from ExecutorService in the above code). I was looking into the setInterval method present in javascript but am not sue how to frame this code using it.
I am free to use jQuery or javascript to get this work. Please advise.
Instead of trying to push from the server, you should have the client make an AJAX request every five seconds, and you should return the snippet that you want printed from that endpoint.
I am reading this topic about java Thread.
And there is an example:
import java.util.Vector;
class Producer extends Thread {
static final int MAXQUEUE = 5;
private Vector messages = new Vector();
#Override
public void run() {
try {
while (true) {
putMessage();
//sleep(5000);
}
} catch (InterruptedException e) {
}
}
private synchronized void putMessage() throws InterruptedException {
while (messages.size() == MAXQUEUE) {
wait();
}
messages.addElement(new java.util.Date().toString());
System.out.println("put message");
notify();
//Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object.
}
// Called by Consumer
public synchronized String getMessage() throws InterruptedException {
notify();
while (messages.size() == 0) {
wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.
}
String message = (String) messages.firstElement();
messages.removeElement(message);
return message;
}
}
class Consumer extends Thread {
Producer producer;
Consumer(Producer p) {
producer = p;
}
#Override
public void run() {
try {
while (true) {
String message = producer.getMessage();
System.out.println("Got message: " + message);
//sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
Producer producer = new Producer();
producer.start();
new Consumer(producer).start();
}
}
And the author said:
A possible output sequence:
Got message: Fri Dec 02 21:37:21 EST 2011
put message
put message
put message
put message
put message
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
put message
put message
put message
put message
put message
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
But when I run this code I got this result:
put message
put message
put message
put message
put message
put message
Got message: Tue Sep 24 16:44:59 CST 2013
Got message: Tue Sep 24 16:45:00 CST 2013
put message
Got message: Tue Sep 24 16:45:00 CST 2013
put message
Got message: Tue Sep 24 16:45:00 CST 2013
put message
..............
What is the problem?
Any one can explain it for me?
The author's entire point is that the order of tasks between different threads is unpredictable. He printed a possible output sequence, but many, many others are possible.
In addition to the already explained output I must add that the book you are reading doesn't seem to be a very good source to learn from. It teaches to:
extend Thread, a notorious bad practice;
invoke wait and notify on a Thread instance—another known, documented bad practice.
use the wait and notify mechanism in the first place, which has mostly been superseded by much more convenient and simpler java.util.concurrent tools such as CountDownLatch, Semaphore, and Phaser.
Your version of output is correct. Because "Got Message" is not possible without "put message". I mean, if there is no message in queue then how can you retrieve the message. Developer in his example might have given sample output which was not actual code run output but self made just for example.
Remember :
[Count of total "Got message" till particular line] will always be <= [Count of total "put message" till that very line]
The only strange thing is that there are 6 consecutive "put message" which seems to be impossible because the maximum queue size is 5.
But this is because the code sequence
producer.getMessage()
System.out.println("Got message: " + message);
is - of course - not atomic and has been interrupted by a thread switch.
By the way - always use notifyAll() instead of notify.
I need my java app to be updated on all the new tweet with a specific hashtag (let's say #test) with twitter4j. Due to avoiding continuous polling on twitter REST API I'll gonna use Twitter Stream API.
Running this code I'm expecting to:
Run the code
Open a browser, go to twitter and post the a tweet that contains #test
See the print on my app only for tweet with a certain hashcode
But.. I do not see anything in my app.. (SEE THE EDIT)
Someone can give me some advice?
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey(CONSUMER_KEY)
.setOAuthConsumerSecret(CONSUMER_SECRET)
.setOAuthAccessToken(ACCESS_TOKEN)
.setOAuthAccessTokenSecret(ACCESS_TOKEN_SECRET);
TwitterStream twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
StatusListener listener = new StatusListener() {
#Override
public void onStatus(Status status) {
System.out.println("#" + status.getUser().getScreenName() + " - " + status.getUser().getId() + " - " + status.getText());
}
#Override
public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
System.out.println("Post Deletado:" + statusDeletionNotice.getStatusId());
}
#Override
public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
System.err.println("Limitação:" + numberOfLimitedStatuses);
}
#Override
public void onScrubGeo(long userId, long upToStatusId) {
System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
}
#Override
public void onStallWarning(StallWarning warning) {
System.out.println("Got stall warning:" + warning);
}
#Override
public void onException(Exception ex) {
ex.printStackTrace();
}
};
List<String> queries = new ArrayList<String>();
queries.add("#test");
twitterStream.addListener(listener);
twitterStream.firehose(20);
String[] trackQueries = (String[]) queries.toArray(new String[queries.size()]);
FilterQuery filterQuery = new FilterQuery();
twitterStream.filter(filterQuery.track(trackQueries));
EDIT:
After some errors fixed I'm reading something in the sys.out but.. it seems random stuffs after some errors:
[Tue Jul 02 14:58:30 CEST 2013]Establishing connection.
[Tue Jul 02 14:58:30 CEST 2013]Establishing connection.
[Tue Jul 02 14:58:31 CEST 2013]Connection established.
[Tue Jul 02 14:58:31 CEST 2013]Receiving status stream.
[Tue Jul 02 14:58:31 CEST 2013]Connection established.
[Tue Jul 02 14:58:31 CEST 2013]Receiving status stream.
[Tue Jul 02 14:58:31 CEST 2013]Stream closed.
[Tue Jul 02 14:58:31 CEST 2013]Stream closed.
[Tue Jul 02 14:58:31 CEST 2013]Waiting for 250 milliseconds
Stream closed.
Relevant discussions can be found on the Internet at:
http://www.google.co.jp/search?q=a8fd061d or
http://www.google.co.jp/search?q=00070a0c
TwitterException{exceptionCode=[a8fd061d-00070a0c a8fd061d-0007099d], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.3}
at twitter4j.StatusStreamBase.handleNextElement(StatusStreamBase.java:199)
at twitter4j.StatusStreamImpl.next(StatusStreamImpl.java:57)
at twitter4j.TwitterStreamImpl$TwitterStreamConsumer.run(TwitterStreamImpl.java:478)
Caused by: java.io.IOException: the end of the stream has been reached
at twitter4j.StatusStreamBase.handleNextElement(StatusStreamBase.java:88)
... 2 more
Stream closed.
Relevant discussions can be found on the Internet at:
http://www.google.co.jp/search?q=a8fd061d or
http://www.google.co.jp/search?q=00070a0c
TwitterException{exceptionCode=[a8fd061d-00070a0c a8fd061d-0007099d], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.3}
at twitter4j.StatusStreamBase.handleNextElement(StatusStreamBase.java:199)
at twitter4j.StatusStreamImpl.next(StatusStreamImpl.java:57)
at twitter4j.TwitterStreamImpl$TwitterStreamConsumer.run(TwitterStreamImpl.java:478)
Caused by: java.io.IOException: the end of the stream has been reached
at twitter4j.StatusStreamBase.handleNextElement(StatusStreamBase.java:88)
... 2 more
[Tue Jul 02 14:58:31 CEST 2013]Unhandled event: {"disconnect":{"code":7,"stream_name":"urbanspirit5-statuses1734930","reason":"admin logout"}}
[Tue Jul 02 14:58:32 CEST 2013]Establishing connection.
[Tue Jul 02 14:58:33 CEST 2013]Connection established.
[Tue Jul 02 14:58:33 CEST 2013]Receiving status stream.
And then some random tweets like this:
#markinhos_jm - 300044892 - CRAZY PARTY AGUARDEM!!!
#bindibba7 - 511548205 - ??????? .. ??????? = ?? ??? ????
#Tamirmdty - 1521605059 - Salah ngetik
#PAOLOves_you - 222755754 - Hirap ah. Text, Chat FB at Tweet? SIYET! #MedyoAZARitu
#agokichi_mmmm - 793252368 - ???DVD??????
Access to twitter firehose is only given to selected companies via resellers. So unless you are one of those companies, you want to use sample() instead of firehose. You should see some logs though. Are you sure your loggers are set up correctly?
EDIT: Read this section of the documentation and add a valid twitter4j.properties file. Note that you have to sign up with twitter to get an access token. Once you have a token and filled the config file, you can just include it in your classpath.
I am trying to load up my own UDF in pig. I have made it into a jar using eclipse's export function. I am trying to run it locally so I can make sure it works before I put the jar on HDFS. When running it locally, I get the following error:
ERROR 1070: Could not resolve myudfs.MONTH using imports: [, org.apache.pig.builtin., org.apache.pig.impl.builtin.]
Script
REGISTER myudfs.jar;
--DEFINE MONTH myudfs.MONTH;
A = load 'access_log_Jul95' using PigStorage(' ') as (ip:chararray, dash1:chararray, dash2:chararray, date:chararray, getRequset:chararray, status:int, port:int);
B = FOREACH A GENERATE myudfs.MONTH(date);
DUMP B;
Function
package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import org.apache.pig.impl.util.WrappedIOException;
#SuppressWarnings("deprecation")
public class HOUR extends EvalFunc<String>
{
public String exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return null;
try{
String str = (String)input.get(0);
return str.substring(1, 3);
}catch(Exception e){
throw WrappedIOException.wrap("Caught exception processing input row ", e);
}
}
}
Working Directory
1.pig 2.pig bin myudfs.jar
pig.jar pig-withouthadoop.jar src/
Running command
pig -x local 2.pig
Structure of jar
0 Thu May 02 12:16:26 MDT 2013 META-INF/
68 Thu May 02 12:16:26 MDT 2013 META-INF/MANIFEST.MF
0 Thu May 02 12:05:50 MDT 2013 myudfs/
573 Thu May 02 12:15:10 MDT 2013 myudfs/HOUR.java
I am really close to start chucking monitors, so I am just looking for some help and direction. Let me know what could be wrong.
Your UDF class name is called HOUR
So shouldn't your pig latin be this?
B = FOREACH A GENERATE myudfs.HOUR(date);