Picky host (lock?) - java

I believe my problem can be considered regardless of used language but, to have some 'anchor', I'll describe it using the Java language.
Let's consider the following scenario:
I have a class PickyHost extending Thread and an instance of it, pickyHostInst running.
That class might look like this:
class PickyHost extends Thread {
private ArrayList<Guest> guests;
public void enter(Guest g) {
// deal with g
}
private void pickGuests() {
// ...
}
public void run() {
// listen indefinitely
}
}
Moreover, in the background, I have many Guest instances running (they also extend Thread class) and once in a while, some guest wants to invoke enter method on pickyHostInst with an argument g being itself.
Now, I want PickyHost to be picky in the following sense:
Immediately after someone invokes enter method, it puts g at the end of guests list and forces g to wait for notification. Also (I think here lies the crux of the matter) it goes itself for a 5 seconds sleep and somehow allows (during these 5 seconds) other guests to invoke enter method (if so happens, then it forgets about how long it had to sleep and resets its alarm clock to sleep exactly 5 seconds again) - I'll call it a sensitive sleep.
As you can see, the total amount of time pickyHostInst sleeps can be huge if many guests arrive - like: A arrives, then after 4 seconds B arrives, then after another 4 seconds C arrives and so on. However, suppose there's been created a chain A, B, ..., G of guests and from the moment of arrival of G till 5 seconds later, no-one arrived.
Then I want pickyHostInst to invoke pickGuests method which, using some algorithm, determines a subset S of {A, B, ..., G} of guests to notify that they can stop waiting and carry on doing what they normally do and moreover removes elements of S from guests list. Method pickGuests can take some time to accomplish and in the meantime some guest H might have arrived and invoked enter - then enter should proceed normally but pickGuests should ignore H and to the end of its last invocation deal with {A, B, ..., G} - not with {A, B, ..., G, H}.
After finishing pickGuests, pickyHostInst should (here I have 2 ideas - implementing any of them will make me happy :))
either
fall again into 5 seconds of sensitive sleep after which, if no guest after H arrived, invoke pickGuests again, or
simultaneously serves guests via enter method as usual but invokes pickGuests only after
max("a moment when last guest from S (from the last invocation) notifies pickyHostInst (like: the last "Thank you, Mr Host" from among S)", "a moment 5 seconds after the last (newest) guest invoked enter").
Finally, after a long introduction, my question - which tools do I need to accomplish such task? I'm unfortunately a bit lost among the richness of various locks and multithreading/locking mechanisms and can't discern which one fits to my problem (or which ones, combined somehow).
I'll greatly appreciate some code-sketches that would put me on the right track.

You can use a java.util.Timer object, which can be reset in the enter method. The timer task will run in its own thread and do the picking for you if it is not canceled before hand.
Note that the enter method will be running on one of the many Guest threads. This means that it should probably synchronized. The easiest way to do this is is to add the synchronized keyword to the method declaration in Java: public synchronized void enter(Guest g). This will ensure that only one guest can enter at a time. You can put the timer cancel/restart code in here.
The way java.util.Timer works it through the abstract java.util.TimerTask class. This is a type of Runnable that also has a method to cancel the task. My recommendation is to schedule a task that will pick guests after a 5000ms interval whenever a guest enters. If a task from the previous guest is running, cancel it first.
The enter method should acquire the guest's lock (using a synchronized block) and have the guest wait. The picking should call the notify() method on the guests you select. This will allow them to continue executing.
When you remove selected guests from your queue, be aware of the fact that Java collections are not thread-safe by default. You will have to use an external lock to ensure that no-one else is modifying your list when you add and remove guests. The Collections.synchronizedList(List) method provides a handy way to do this.
Here is a list of links that discuss the topics I have mentioned:
http://docs.oracle.com/javase/tutorial/essential/concurrency/ (excellent tutorial for beginners)
http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
http://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html
http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList%28java.util.List%29

I might do this like this. I'd try to avoid notify/notifyAll as you'll have to involve a flag because of spurious wakeups and that clutters the code quite a bit. CountDownLatch is a much better choice here IMO even though the name is a bit weird.
static final long five_sec = TimeUnit.SECOND.toNanos(5)
final Queue<Pair<Guest, CountDownLatch>> guests = new LinkedList<>();
long earliest = -1;
// Synchronizing on "this" is fine but using private lock
// object is even better
final Object lock = new Object();
void enter(Guest g){
Pair p = Pair.of(g, new CountDownLatch(1));
synchronized(lock){
guests.get().add(p);
earliest = System.nanoTime() + five_sec;
}
p.second.await();
}
void pickGuests(){
synchronized(lock){
// pop a few guests from sofar and wake them
Guest g = sofar.poll();
if(g != null){
g.second.countDown();
}
}
}
void run(){
while(!Thread.currentThread().isInterrupted()){
long sleepTime;
synchronized(lock){
if(System.nanoTime() > earliest){
pickGuests();
}
sleepTime = earliest - System.nanoTime();
sleepTime = sleepTime < five_sec ? five_sec : sleepTime;
}
Thread.sleep(sleepTime);
}
}

Related

Why my input is showing one thread executing after another thread, not at the same time?

I researched the concept of a thread and saw that it is to have code run in two processes at the same time. Heres my code though
public class Connor extends Thread{
public void run() {
for(int i=0; i< 10; i ++){
System.out.println("Hello " + i);
}
public static void main(String[] args){
Connor runner1 = new Connor();
Connor runner2 = new Connor();
runner1.start();
runner2.start();
}
}
And my output http://imgur.com/yAZqgal
It seems like the two threads do start off at the same time(separate processes, as indicated by the two leading 0s) but one executes (1-9) and then the other executes (1-9). Arent they suppose to interweave as well (1,1,2,2,...) bc the threads both print to the console. I researched and saw that start is the right method to use as it tells the thread class to execute the run method in another thread? Can anyone explain why im getting this output?
Say you have ten errands you need to do and your sister has ten errands she needs to do, and you only have one car. Do you bring the car back after each errand and switch drivers? Of course not. That would be absurdly inefficient. Each thread basically just needs the output stream. So it would be absurd to interleave them tightly.
Your code looks fine. I guess that your threads do not run in parallel just because they terminate to fast. Change the loop limit from 10 to 1000 and you will see the effect.
Starting thread itself is relatively heavy operation. You code starts the first thread and then the second one. The first thread once started terminates before the second thread got a chance to start executing its business logic.
In case of Multi-threading there is no guarantee that which thread is allocated for what time to run by the processor and in that case the result is unpredictable and will generate different output for each run.
If you are looking for desired output then you need synchronization block. using wait and notify you can achieve it easily.
Please have a look at below Lesson directly from Oracle official site:
Lesson: Concurrency to read more about concurrency.
Chapter 17. Threads and Locks to read more about thread, locks and synchronization.
Note: wait & notify must be called inside the synchronized block and can call on the same object on which it is synchronized.
Sample code: (read inline comments)
public class Connor extends Thread {
private static Connor runner1 = new Connor();
private static Connor runner2 = new Connor();
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Hello " + i);
// wake up another thread to come out from wait state
if (runner1 == this) {
// wake up runner2
synchronized (runner2) {
runner2.notify();
}
} else {
// wake up runner1
synchronized (runner1) {
runner1.notify();
}
}
synchronized (this) {
try {
// say current thread to wait until notify by another thread
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
runner1.start();
runner2.start();
}
}
output:
Hello 0
Hello 0
Hello 1
Hello 1
Hello 2
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4
Hello 5
Hello 5
Hello 6
Hello 6
Hello 7
Hello 7
Hello 8
Hello 8
Hello 9
Hello 9
Why my input is showing one thread executing after another thread, not at the same time?
The general explanation is that Thread scheduling is unpredictable. Interleaving may happen ... or it may not. That is fundamental to Java threading. (And indeed to threading in most other languages.)
If you need thread execution to interleave in an entirely predictable way, you need to implement some kind of hand-shake mechanism, where one thread waits for another one to do something, and do on. But that is complicated, and typically defeats the purpose of using threading.
FWIW: #Braj's answer shows how you might implement strict interleaving. However note that this effectively means that only one thread is going to execute at a time. In addition, the waiting / notifying is going to lead to a lot of work for the thread scheduler ... some that the application will run significantly slower than if you had just done the work on one thread.
In this particular example, there are two issues that combine to make any short term interleaving unlikely:
Creating a new native thread in Java is relatively expensive, because it typically entails requesting a memory block from the OS to house the thread stack. That in turn entails the OS "messing around" with page tables, zeroing a memory block and so on.
Native thread scheduling is implemented by the operating system, and it operates at a fairly coarse-grained level ... because that is the most efficient way to operate from the perspective of a typical application. (Switching thread "contexts" in a PC-class machine is relatively expensive operation, and the thread scheduler itself potentially has work to do.)
In your example, the chances are that the first thread can say "hello" ten times before the second thread is ready to be scheduled.

Dynamic Scheduled Concurrent Task Execution in Java

I'm trying to implement an application that programs tasks based on some user input. The users can put a number of IPs with telnet commands associated with them (one to one relationship), a frequency of execution, and 2 groups (cluster, objectClass).
The user should be able to add/remove IPs, Clusters, commands, etc, at runtime. They should also be able to interrupt the executions.
This application should be able to send the telnet commands to the IPs, wait for a response and save the response in a database based on the frequency. The problem I'm having is trying to make all of this multithreaded, because there are at least 60,000 IPs to telnet, and doing it in a single thread would take too much time. One thread should process a group of IPs in the same cluster with the same objectClass.
I've looked at Quartz to schedule the jobs. With Quartz I tried to make a dynamic job that took a list of IPs (with commands), processed them and saved the result to database. But then I ran into the problem of the different timers that users gave. The examples on the Quartz webpage are incomplete and don't go too much into detail.
Then I tried to do it the old fashioned way, using java Threads, but I need to have exception handling and parameter passing, Threads don't do that. Then I discovered the Callables and Executors but I can't schedule tasks with Callables.
So Now I'm stumped, what do I do?
OK, here are some ideas. Take with the requisite grain of salt.
First, create a list of all of the work that you need to do. I assume you have this in tables somewhere and you can make a join that looks like this:
cluster | objectClass | ip-address | command | frequency | last-run-time
this represents all of the work your system needs to do. For the sake of explanation, I'll say frequency can take the form of "1 per day", "1 per hour", "4 per hour", "every minute". This table has one row per (cluster,objectClass,ip-address,command). Assume a different table has a history of runs, with error messages and other things.
Now what you need to do is read that table, and schedule the work. For scheduling use one of these:
ScheduledExecutorService exec = Executors...
When you schedule something, you need to tell it how often to run (easy enough with the frequencies we've given), and a delay. If something is to run every minute and it last ran 4 min 30 seconds ago, the initial delay is zero. If something is to run each hour the the initial delay is (60 min - 4.5 min = 55.5 min).
ScheduledFuture<?> handle = exec.scheduleAtFixedRate(...);
More complex types of scheduling are why things like Quartz exist, but basically you just need a way to resolve, given(schedule, last-run) an elapsed time to the next execution. If you can do that, then instead of scheduleAtFixedRate(...) you can use schedule(...) and then schedule the next run of a task as that task completes.
Anyway, when you schedule something, you'll get a handle back to it
ScheduledFuture<?> handle = exec.scheduleAtFixedRate(...);
Hold this handle in something that's accessible. For the sake of argument let's say it's a map by TaskKey. TaskKey is (cluster | objectClass | ip-address | command) together as an object.
Map<TaskKey,ScheduledFuture<?>> tasks = ...;
You can use that handle to cancel and schedule new jobs.
cancelForCustomer(CustomerId id) {
List<TaskKey> keys = db.findAllTasksOwnedByCustomer(id);
for(TaskKey key : keys) {
ScheduledFuture<?> f = tasks.get(key);
if(f!=null) f.cancel();
}
}
For parameter passing, create an object to represent your work. Create one of these with all the parameters you need.
class HostCheck implements Runnable {
private final Address host;
private final String command;
private final int something;
public HostCheck(Address host, String command; int something) {
this.host = host; this.command = command; this.something = something;
}
....
}
For exception handling, localize that all into your object
class HostCheck implements Runnable {
...
public void run() {
try {
check();
scheduleNextRun(); // optionally, if fixed-rate doesn't work
} catch( Exception e ) {
db.markFailure(task); // or however.
// Point is tell somebody about the failure.
// You can use this to decide to stop scheduling checks for the host
// or whatever, but just record the info now and us it to influence
// future behavior in, er, the future.
}
}
}
OK, so up to this point I think we're in pretty good shape. Lots of detail to fill in but it feels manageable. Now we get to some complexity, and that's the requirement that execution of "cluster/objectClass" pairs are serial.
There are a couple of ways to handle this.
If the number of unique pairs are low, you can just make Map<ClusterObjectClassPair,ScheduledExecutorService>, making sure to create single-threaded executor services (e.g., Executors.newSingleThreadScheduledExecutor()). So instead of a single scheduling service (exec, above), you have a bunch. Simple enough.
If you need to control the amount of work you attempt concurrently, then you can have each HealthCheck acquire a permit before execution. Have some global permit object
public static final Semaphore permits = java.util.concurrent.Semaphore(30);
And then
class HostCheck implements Runnable {
...
public void run() {
permits.acquire()
try {
check();
scheduleNextRun();
} catch( Exception e ) {
// regular handling
} finally {
permits.release();
}
}
}
You only have one thread per ClusterObjectClassPair, which serializes that work, and then permits just limit how many ClusterObjectClassPair you can talk to at a time.
I guess this turned it a quite a long answer. Good luck.

join() doesn't block other threads (except main)?

Our teacher gave us the following code:
public static void main(String[]args) {
Thread a = new Thread(new T(2));
Thread b = new Thread(new T(5));
a.start();
b.start();
try {
a.join(); //Thread a now runs completely to the end, before the main-method gets back to a "runnable" state
b.join(); //Thread b runs to death before the main methods u
} catch (InterruptedException ie) {}
System.out.println("done"); //Result: Random Thread a and b outputs
//and in the end "done" from main
}
public class T extends Thread {
private int nr;
public T(int nr) {
this.nr = nr;
}
public void run() {
for (int i=0; i<10; i++) {
System.out.println("Hello " + nr + " " + i);
}
}
Thread a and b are the same and both write (in a for-loop) 10 prints to the console.
Thread a and b were finished, before the main method stopped and all results were random except the main method.
My question was, if it shouldn't also block the other threads(not just main), if you call join() on one thread. He said, that join() just freezes the main method. But for what reason should this be good? He also said, that this is totally random and managed by the scheduler, which doesn't make sense for this part in my opinion (the scheduler commands the thread-states, this is clear, but not after calling join(), at least not for the java application. Or am I false?). My point would be, that Thread a and b ran completely to the end, before the main-thread even called the join method. Javadoc tells me the same, if I understand it correct.
I hope someone of you can give me an answer. :)
The call to join() on an instance of Thread will not complete until the thread corresponding to that instance dies.
Corrollary 1: if that thread is already dead, join() returns immediately.
Corrollary 2: no threads except the current are affected by this call.
He also said, that this is totally random and managed by the scheduler
You probably didn't catch exactly what the teacher said here. Thread scheduling, which means making decisions when a thread will be given some CPU time to run, and how much of it, is done by the thread scheduler. It is definitely not "totally random" and for most practical considerations, all threads run all the time. Again, this has little to do with the behavior of the join method.
The point of join is not to give a single thread priority over all others. Rather, it's to express that one thread needs to wait for another thread to complete before that (first) thread can go on. It's not always the main thread calling join. It's a single constraint being placed on the scheduler: "Don't do A until you've done B". Of course, by using multiple joins, you can accomplish more complex dependencies.
I suspect that the point your teacher was trying to make is that you cannot assume anything other than the contract of join. I.e. the main thread will not continue until a has run to completion.
It is quite possible for a.join() to allow b to continue but it is also possible for it to completely block b until a is complete.
If you tested this code on a single-core machine it is actually quite likely that a.join() will exclude b but on a multi-core machine it may not.

Best way to wait in Java

I have an app that needs to wait for some unknown amount of time. It must wait until several data fields are finished being populated by a server.
The server's API provides me a way to request data, easy enough...
The server's API also provides a way to receive my data back, one field at a time. It does not tell me when all of the fields are finished being populated.
What is the most efficient way to wait until my request is finished being processed by the server? Here's some pseudocode:
public class ServerRequestMethods {
public void requestData();
}
public interface ServerDeliveryMethods {
public void receiveData(String field, int value);
}
public class MyApp extends ServerRequestMethods implements ServerDeliveryMethods {
//store data fields and their respective values
public Hashtable<String, Integer> myData;
//implement required ServerDeliveryMethods
public void receiveData(String field, int value) {
myData.put(field, value);
}
public static void main(String[] args) {
this.requestData();
// Now I have to wait for all of the fields to be populated,
// so that I can decide what to do next.
decideWhatToDoNext();
doIt();
}
}
I have to wait until the server is finished populating my data fields, and the server doesn't let me know when the request is complete. So I must keep checking whether or not my request has finished processing. What is the most efficient way to do this?
wait() and notify(), with a method guarding the while loop that checks if I have all of the required values yet every time I'm woken up by notify()?
Observer and Observable, with a method that checks if I have the all the required values yet every time my Observer.Update() is called?
What's the best approach? Thanks.
If I understood you right, some other thread calls receiveData on your MyApp to fill the data. If that's right, then here's how you do it:
You sleep like this:
do {
this.wait(someSmallTime); //We are aquiring a monitor on "this" object, so it would require a notification. You should put some time (like 100msec maybe) to prevent very rare but still possible deadlock, when notification came before this.wait was called.
} while (!allFieldsAreFilled());
receiveData should make a notify call, to unpause that wait call of yours. For example like this:
myData.put(field, value);
this.notify();
Both blocks will need to be "synchronized" on this object to be able to aquire it's monitor (that's needed for wait). You need to either declare the methods as "synchronized", or put the respective blocks inside synchronized(this) {...} block.
Use a CompletionService
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CompletionService.html
i think the most efficient method is with wait and notify. You can set a Thread into sleep with wait(). You can wake up the Thread from another one, e.g. your server with notify() to wake up. wait() is a blocking method, you dont have to poll anything. You can also use the static method Thread.sleep(milliseconds) to wait for a time. If you put sleep into a endless while loop checking for a condition with a continusly wait time, youll wait also.
I prefer wait() and notify(), its most efficient at all.
Pretty old question, but I looked for similar problem and found a solution.
At first, developer should never create a thread that will wait forever. You really have to create 'exit condition' if you are using 'while' cycle. Also, waiting for 'InterruptedException' is tricky. If another thread doesn't call yourThread.interrupt() you'll wait until program truly ends.
I used java.util.concurrent.CountDownLatch so in short:
/*as field*/
CountDownLatch semaphore = new CountDownLatch(1);
/*waiting code*/
boolean timeout = !semaphore.await(10, TimeUnit.SECONDS);
/*releasing code*/
semaphore.countDown();
As result, 'waiting code' thread will wait until some another Thread calls 'releasing code' or will "timeout". If you want to wait for 10 fields to be populated, then use 'new CountDownLatch(10)'.
This principle is similar for 'java.util.concurrent.Semaphore' but semaphore is better for access locking and that isn't your case, indeed.
It seems like many people have been having trouble with this (myself included) but I have found an easy and sleek solution. Use this method:
public static void delay(int time) {
long endTime = System.currentTimeMillis() + time;
while (System.currentTimeMillis() < endTime)
{
// do nothing
}
}
This gets the current time and sets an end time (current time + time to wait) and waits until the current time hits the end time.

How would I make a thread join on another thread but only wait for n seconds of CPU time?

otherThread.join( time ) appears to wait time in real milliseconds. I want to wait time in actual CPU time so that I can get consistent behavior within my application.
I've done a quick look at ThreadMXBean but that doesn't quite seem to have what I wanted ( it tells me the threads actual CPU time, but offers no convenient way to wait until some time has passed ) . A busy loop around a sleep() could work, but seems grossly inefficient.
I also thought about using another thread and waiting on a Condition, but I'm not sure how that would work. The main thread would do: myCondition.await() , where another thread that would toggle myCondition when otherThread had used time actual CPU time. Again, this seems complicated and would probably still require the controlling thread to have a busy loop.
Edit: I'm doing this for a grading script. This means that I need to have a way to timeout if the student is in an infinite loop and it needs to be fair. I've been using JUnit to run tests on students, but that has the same problem with timing out: if the same (inefficient) submission is run multiple times, it could possibly get different grades depending on what other jobs are running on the machine at the time (a real problem for group work).
But this is a problem with normal unit testing, too - by using clock time instead of CPU time JUnit gets inconsistent test results?
I'd suggest running a single JVM test at a time, and using time (see man time for details) to determine actual CPU time used. As for interrupting it if it takes too long... You could probably accomplish that with a shell script, or just allow the process to run to completion and base grading on the actual time taken.
Not going to happen. A timed join() is based on wall clock time, which means a hardware timer can be set to provide an asynchronous interrupt x seconds from now if the thread hasn't already been exited. Since there's no way to know a priori how much CPU a thread will use and therefore no way to schedule an interrupt when some boundary is reached. CPU time is accounted for when a process yields its time slice voluntarily or by force, so there wouldn't be any way to hit some exact figure anyway.
The closest you'd be able to get is polling the CPU utilization every so often and invoking interrupt() on threads that have gone over the limit. (Study the semantics of that carefully, because interrupting a thread will not necessarily bring the thread to an immediate stop.) If all you care about is whether or not the thread has consumed more than x seconds of CPU time, late checks that get results like kx where k > 1 aren't going to matter. They're still greater than x, and that's enough to know your candidate went over the limit.
One thing you could do if you're on a Unix-y system is to run the entire assignment as a process and use ulimit to limit the amount of CPU it's allowed to some value with a reasonable amount tacked on for JVM startup and program load.
Think about what you're asking for: you want a thread to block (not use CPU time) until it has used a specified amount of CPU time. This doesn't make sense.
I suspect what you really want if for your thread to block until another thread has used a specified amount of CPU time. This is not easily provided, probably because it is so rarely useful and can lead you down paths to poorly behaving code.
I think if you combine thread.join()/interrupt() strategy (for timing out bad code (infinite loops)) and testingThread calling back cpu time you get what you want, if I´m not missing something. The solution may follow an approach like:
public class GradingThread extends Thread {
private Thread testThread;
private long elapsedClockTime=-1;
public GradingThread(TestingThread testThread){
this.testThread = testThread;
testThread.setGradingThread(this);
}
public void setElapsed(long elapsedClockTime){
this.elapsedClockTime = elapsedClockTime;
}
public void run(){
System.out.println("GradingThread ID="+Thread.currentThread().getId());
try{
testThread.start();
testThread.join(5000);
testThread.interrupt();
}catch(Exception e){e.printStackTrace();}
if(elapsedClockTime==-1){
System.out.println("Student program timedout (more than 5000 clock seconds)");
}else{
System.out.println("Student program elapsed cpu time = "+(elapsedClockTime)/1000000+"ms");
}
}
public static void main(String[] args) {
(new GradingThread(new TestingThread())).start();
}
}
public class TestingThread extends Thread {
private GradingThread gradingThread;
public void setGradingThread(GradingThread thread){
gradingThread = thread;
}
public void run(){
StudentProgram sp = new StudentProgram();
System.out.println("TestingThrad ID="+Thread.currentThread().getId());
long scpu = getCpuTime();
sp.takeLessThan5WallSecondsToRun(); //try calling infiniteLoop() too.
long ecpu = getCpuTime();
gradingThread.setElapsed(ecpu - scpu);
}
/** Get CPU time in nanoseconds. */
public long getCpuTime( ) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
if ( ! bean.isCurrentThreadCpuTimeSupported())
return -1L;
long time = bean.getThreadCpuTime(Thread.currentThread().getId());
return time;
}
}//end of TestingThread.
class StudentProgram {
public void infiniteLoop(){
while(true);
}
public int takeLessThan5WallSecondsToRun(){
int total=0;
while(total < Integer.MAX_VALUE) total++;
return total;
}
}//end of StudentProgram.

Categories