Preserve call stack of, Timer.schedule in java - java

I have a daemon thread running which calls a function (prepareOrder) whenever the cook is not busy and there are orders to be delivered. The prepareOrder calls the orderComplete function after a certain interval of time depending upon the time required to complete the order. Now the problem i am facing is only the last call to the prepareOrder gets displayed on sout.
The daemon
package ui;
import Model.takeOrderModel;
public class daemonThread extends Thread{
//call this method in the main method of driving fucntion
private takeOrderModel orderModel;
daemonThread(takeOrderModel orderModel){
this.orderModel = orderModel;
}
public void assignCook(){
while(true){
int toComplete = orderModel.toCompleteOrders.size();
if ( !orderModel.cookBusy && toComplete>0 ) orderModel.prepareOrder();
}
}
}
The prepare order function.
public void prepareOrder(){
// pick the last element from list
if (toCompleteOrders.size() > 0){
String nextPrepare = toCompleteOrders.get(toCompleteOrders.size()-1);
order orderToComplete = allOrdersPlaced.get(nextPrepare);
completeOrder(orderToComplete);
toCompleteOrders.remove(nextPrepare);
}
}
//Helper function to prepareOrder moves an order from toComplete to prepared order
private void completeOrder(order orderToComplete){
changeCookState();
new java.util.Timer().schedule(
new java.util.TimerTask(){
#Override
public void run() {
changeCookState();
preparedOrders.add(orderToComplete.id);
deliverOrder(orderToComplete.id);
}
}, (long) (orderToComplete.timeToComplete*60)
);
}
public void changeCookState(){
this.cookBusy = !cookBusy;
}
// MODIFIES removes a order from the prepared list and puts it in delivered list
public String deliverOrder(String completedOrder){
preparedOrders.remove(completedOrder);
deliveredOrders.add(completedOrder);
System.out.println(String.format("The order of %s is here", allOrdersPlaced.get(completedOrder).customerName));
return String.format("The order of %s is here", allOrdersPlaced.get(completedOrder).customerName);
}
The main function driving code.
orderMachine.takeNewOrder(fullMeal, "Tom");
orderMachine.takeNewOrder(halfMeal, "Bob");
daemonThread backThread = new daemonThread(orderMachine);
backThread.setDaemon(true);
backThread.assignCook();
Now for me only the last placed order("Bob") gets printed on sout. How can all calls created by Timer.schedule stay in stack.
Edits
The take new order function.
public boolean takeNewOrder(List<item> itemsInOrder, String customerName){
try {
order newOrder = new order(itemsInOrder, customerName);
allOrdersPlaced.put(newOrder.id, newOrder);
toCompleteOrders.add(newOrder.id);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Edit 2
here is the public repo containing the complete code
https://github.com/oreanroy/Share_code_samples/tree/master/takeOrder

The problem in this code is a concurrency bug - the cookBusy variable is being written to from two different threads. To fix this, use an AtomicBoolean instead of a boolean, as this is thread safe.
AtomicBoolean cookBusy = new AtomicBoolean(false);
Use compareAndSet to ensure the shared variable is set to a known value before updating it.
public void changeCookState(boolean busy){
if (!this.cookBusy.compareAndSet(!busy, busy))
{
throw new RuntimeException("shared variable set to unexpected value");
}
}

Related

Retrieve the observed value from Californium CoAP client

I am trying to implement a CoAP client based on Californium. I make this client observing to a resource:
public static class CoapCl{
double val = 0;
CoapClient client = new CoapClient("coap://localhost/Ultrasonic");
CoapObserveRelation relation = client.observe(new CoapHandler() {
#Override public void onLoad(CoapResponse response)
{
val = Double.parseDouble(response.getResponseText());
}
#Override
public void onError() {
System.out.println("Failed");
}
});
}
I want to access the value "val" from another class. How can I do it ? I tried to call a reference from the CoapCl class like this and print the value out:
CoapCl client = new CoapCl();
while(true)
{
System.out.println("Testing: " + client.val);
}
This will print all the value I get from the CoAP client, both changed and unchanged value. What should I do if I only want to get the changed value ?
Well, the issue itself isn't related to Californium and CoAP.
Except that CoapHandler is async but this is rather a strench.
Nevertheless, I'd recommend to end up with some kind of callback:
public class CoapCl {
private final Consumer<Double> valueChangedAction;
private final CoapClient client = new CoapClient("coap://localhost/Ultrasonic");
public CoapCl(Consumer<Double> valueChangedAction) {
this.valueChangedAction = valueChangedAction;
}
public void run() {
client.observe(new CoapHandler() {
#Override
public void onLoad(CoapResponse response) {
valueChangedAction.accept(
Double.parseDouble(
response.getResponseText()
)
);
}
#Override
public void onError() {
System.out.println("Failed");
}
});
}
}
new CoapCl(val -> System.out.println("Testing: " + val)).run();
Please keep in mind you have to block the main thread someway to keep the program from immediate exit.
Before, you had blocked it with your infinite loop.
Now you'll have to use System.in.read() or Thread.sleep or something else if you have no such stuff yet in your program.

Trying to create muliple java instances of a java thread but it appears only one is working

I am trying to run two different instances of a Java thread I created, and I see it create the two threads, but only one thread is being called and used at a time. If I run them separately they work fine, but when I try to run the two threads at the same time only one is being updated.
Here is the pertinent code from a main() method:
for( Properties prop: propList){
Send send = new MainTest().new Send(iterationOffset,prop);
send.start();
}
public class Send extends Thread{
private double iterationOffset;
private Properties prop;
SendEsd(double off, Properties p){
this.iterationOffset = off;
this.prop = p;
}
#Override
public void run() {
while (true) {
String id = prop.get("platform.id").toString();
System.out.println("$$$$$$$$$$$$$$ create Thred : send = " +id);
sendData( iterationOffset, prop );
}
}
private void sendData(double iterationOffset, Properties prop ){
id = prop.get("platform.id").toString();
// *** the itDataList is a really large CSV it inputs,
// so it will spin here a long time
for (it itData : itDataList) {
try {
//*** it will send some data here
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error("Sleep thread was interrupted.");
}
}
}
}

How to implement fair usage policy of threads in API backend?

I am building an REST API in Java which I would be exposing to the outside world. People who would be invoking the API would have to be registered and would be sending their userid in the request.
There would be a maximum of, say, 10 concurrent threads available for executing the API request. I am maintaining a queue which holds all the request ids to be serviced (the primary key of the DB entry).
I need to implement some fair usage policy as follows -
If there are more than 10 jobs in the queue (i.e more than max number of threads), a user is allowed to execute only one request at a time (the other requests submitted by him/her, if any, would remain in the queue and would be taken up only once his previous request has completed execution). In case there are free threads, i.e. even after allotting threads to requests submitted by different users, then the remaining threads in the thread pool can be distributed among the remaining requests (even if the user who has submitted the request is already holding one thread at that moment).
The current implementation is as follows -
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.Semaphore;
public class APIJobExecutor implements Runnable{
private static PriorityBlockingQueue<Integer> jobQueue = new PriorityBlockingQueue<Integer>();
private static ExecutorService jobExecutor = Executors.newCachedThreadPool();
private static final int MAX_THREADS = 10;
private static Semaphore sem = new Semaphore(MAX_THREADS, true);
private APIJobExecutor(){
}
public static void addJob(int jobId)
{
if(!jobQueue.contains(jobId)){
jobQueue.add(new Integer(jobId));
}
}
public void run()
{
while (true) {
try {
sem.acquire();
}catch (InterruptedException e1) {
e1.printStackTrace();
//unable to acquire lock. retry.
continue;
}
try {
Integer jobItem = jobQueue.take();
jobExecutor.submit(new APIJobService(jobItem));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
sem.release();
}
}
}
}
Edit:
Is there any out of the box Java data structure that gives me this functionality. If not, how do I go about implementing the same?
This is a fairly common "quality of service" pattern and can be solved using the bucket idea within a job-queue. I do not know of a standard Java implementation and/or datastructure for this pattern (maybe the PriorityQueue?), but there should be at least a couple of implementations available (let us know if you find a good one).
I did once create my own implementation and I've tried to de-couple it from the project so that you may modify and use it (add unit-tests!). A couple of notes:
a default-queue is used in case QoS is not needed (e.g. if less than 10 jobs are executing).
the basic idea is to store tasks in lists per QoS-key (e.g. the username), and maintain a separate "who is next" list.
it is intended to be used within a job queue (e.g. part of the APIJobExecutor, not a replacement). Part of the job queue's responsibility is to always call remove(taskId) after a task is executed.
there should be no memory leaks: if there are no tasks/jobs in the queue, all internal maps and lists should be empty.
The code:
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.*;
import org.slf4j.*;
/** A FIFO task queue. */
public class QosTaskQueue<TASKTYPE, TASKIDTYPE> {
private static final Logger log = LoggerFactory.getLogger(QosTaskQueue.class);
public static final String EMPTY_STRING = "";
/** Work tasks queued which have no (relevant) QoS key. */
private final ConcurrentLinkedQueue<TASKIDTYPE> defaultQ = new ConcurrentLinkedQueue<TASKIDTYPE>();
private final AtomicInteger taskQSize = new AtomicInteger();
private final Map<TASKIDTYPE, TASKTYPE> queuedTasks = new ConcurrentHashMap<TASKIDTYPE, TASKTYPE>();
/** Amount of tasks in queue before "quality of service" distribution kicks in. */
private int qosThreshold = 10;
/** Indicates if "quality of service" distribution is in effect. */
private volatile boolean usingQos;
/**
* Lock for all modifications to Qos-queues.
* <br>Must be "fair" to ensure adding does not block polling threads forever and vice versa.
*/
private final ReentrantLock qosKeyLock = new ReentrantLock(true);
/*
* Since all QoS modifications can be done by multiple threads simultaneously,
* there is never a good time to add or remove a Qos-key with associated queue.
* There is always a chance that a key is added while being removed and vice versa.
* The simplest solution is to make everything synchronized, which is what qosKeyLock is used for.
*/
private final Map<String, Queue<TASKIDTYPE>> qosQueues = new HashMap<String, Queue<TASKIDTYPE>>();
private final Queue<String> qosTurn = new LinkedList<String>();
public boolean add(TASKTYPE wt, TASKIDTYPE taskId, String qosKey) {
if (queuedTasks.containsKey(taskId)) {
throw new IllegalStateException("Task with ID [" + taskId + "] already enqueued.");
}
queuedTasks.put(taskId, wt);
return addToQ(taskId, qosKey);
}
public TASKTYPE poll() {
TASKIDTYPE taskId = pollQos();
return (taskId == null ? null : queuedTasks.get(taskId));
}
/**
* This method must be called after a task is taken from the queue
* using {#link #poll()} and executed.
*/
public TASKTYPE remove(TASKIDTYPE taskId) {
TASKTYPE wt = queuedTasks.remove(taskId);
if (wt != null) {
taskQSize.decrementAndGet();
}
return wt;
}
private boolean addToQ(TASKIDTYPE taskId, String qosKey) {
if (qosKey == null || qosKey.equals(EMPTY_STRING) || size() < getQosThreshold()) {
defaultQ.add(taskId);
} else {
addSynced(taskId, qosKey);
}
taskQSize.incrementAndGet();
return true;
}
private void addSynced(TASKIDTYPE taskId, String qosKey) {
qosKeyLock.lock();
try {
Queue<TASKIDTYPE> qosQ = qosQueues.get(qosKey);
if (qosQ == null) {
if (!isUsingQos()) {
// Setup QoS mechanics
qosTurn.clear();
qosTurn.add(EMPTY_STRING);
usingQos = true;
}
qosQ = new LinkedList<TASKIDTYPE>();
qosQ.add(taskId);
qosQueues.put(qosKey, qosQ);
qosTurn.add(qosKey);
log.trace("Created QoS queue for {}", qosKey);
} else {
qosQ.add(taskId);
if (log.isTraceEnabled()) {
log.trace("Added task to QoS queue {}, size: " + qosQ.size(), qosKey);
}
}
} finally {
qosKeyLock.unlock();
}
}
private TASKIDTYPE pollQos() {
TASKIDTYPE taskId = null;
qosKeyLock.lock();
try {
taskId = pollQosRecursive();
} finally {
qosKeyLock.unlock();
}
return taskId;
}
/**
* Poll the work task queues according to qosTurn.
* Recursive in case empty QoS queues are removed or defaultQ is empty.
* #return
*/
private TASKIDTYPE pollQosRecursive() {
if (!isUsingQos()) {
// QoS might have been disabled before lock was released or by this recursive method.
return defaultQ.poll();
}
String qosKey = qosTurn.poll();
Queue<TASKIDTYPE> qosQ = (qosKey.equals(EMPTY_STRING) ? defaultQ : qosQueues.get(qosKey));
TASKIDTYPE taskId = qosQ.poll();
if (qosQ == defaultQ) {
// DefaultQ should always be checked, even if it was empty
qosTurn.add(EMPTY_STRING);
if (taskId == null) {
taskId = pollQosRecursive();
} else {
log.trace("Removed task from defaultQ.");
}
} else {
if (taskId == null) {
qosQueues.remove(qosKey);
if (qosQueues.isEmpty()) {
usingQos = false;
}
taskId = pollQosRecursive();
} else {
qosTurn.add(qosKey);
if (log.isTraceEnabled()) {
log.trace("Removed task from QoS queue {}, size: " + qosQ.size(), qosKey);
}
}
}
return taskId;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder(this.getClass().getName());
sb.append(", size: ").append(size());
sb.append(", number of QoS queues: ").append(qosQueues.size());
return sb.toString();
}
public boolean containsTaskId(TASKIDTYPE wid) {
return queuedTasks.containsKey(wid);
}
public int size() {
return taskQSize.get();
}
public void setQosThreshold(int size) {
this.qosThreshold = size;
}
public int getQosThreshold() {
return qosThreshold;
}
public boolean isUsingQos() {
return usingQos;
}
}

List of results from async operations

My goal is to obtain a list of results from 10 (or some other arbitrary number) of asynchronous operations.
I'm using com.google.guava for the utilities in concurrency and if someone could graciously point me in the right direction I would be much appreciative.
In the example I'm trying to get a list of successfulBombs (Bomb being pretty much an empty object but has a random probability of throwing a Problem when created to simulate problems with service call execution)
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
List<ListenableFuture<Bomb>> bombs;
ListenableFuture<List<Bomb>> successfulBombs;
Edit:
This is what I've come up with so far but the list is empty even though it should have some successful elements... I can't quite discern why
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
List<ListenableFuture<Bomb>> bombs = new ArrayList<ListenableFuture<Bomb>>();
for(int i=0;i<10;i++)
{
ListenableFuture<Bomb> bomb = service.submit(new Callable<Bomb>(){
public Bomb call() throws Problem
{
return craftBomb();
}
});
}
ListenableFuture<List<Bomb>> successfulBombs = Futures.successfulAsList(bombs);
Futures.addCallback(successfulBombs, new FutureCallback<List<Bomb>>(){
public void onSuccess(List<Bomb> bombs)
{
System.out.println("My successful bombs");
for(Bomb b : bombs)
{
System.out.println(b);
}
}
public void onFailure(Throwable thrown)
{
System.err.println("There was a problem making this bomb.");
}
});
In closing what I'm looking for:
Correct pattern for starting asynchronous operations
Collecting a List for the resulting operations
Collecting a List of successful operations using the guava Framework
The list is empty because you're never adding anything to bombs. You're passing an empty list to Futures.successfulAsList.
Are you looking for ListeningExecutorService.invokeAll(List<Callable<T>>)? Perhaps combined with Futures.allAsList(List<ListenableFuture<T>>)?
The working solution was as follows
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
List<ListenableFuture<Bomb>> bombs = new ArrayList<ListenableFuture<Bomb>>();
for(int i=0;i<10;i++)
{
ListenableFuture<Bomb> bomb = service.submit(new Callable<Bomb>(){
public Bomb call() throws Problem
{
return craftBomb();
}
});
bombs.add(bomb);
}
ListenableFuture<List<Bomb>> successfulBombs = Futures.successfulAsList(bombs);
Futures.addCallback(successfulBombs, new FutureCallback<List<Bomb>>(){
public void onSuccess(List<Bomb> bombs)
{
System.out.println("My successful bombs");
for(Bomb b : bombs)
{
System.out.println(b);
}
}
public void onFailure(Throwable thrown)
{
System.err.println("There was a problem making this bomb.");
}
});

How can I pass a variable to an inner thread class?

I want to load an image at periodic intervals to an imageitem. My outer class is generating the URL and I need to pass it to the innerclass. How do I achieve this?
public class MapTimer extends TimerTask{
public void run() {
System.out.println("Map starting...");
String URL=null,serverquery=null;
try {
sendMessage(this.message);
item.setLabel(item.getLabel()+"start");
serverquery=receiveMessage();
item.setLabel(item.getLabel()+"stop");
URL = getURL(serverquery); // my url to be passed to innerclass
System.out.println("URl is "+serverquery);
item.setLabel(URL+item.getLabel());
Thread t = new Thread() {
public void run() {
item.setLabel(item.getLabel()+"6");
try {
Image image = loadImage(URL); // using url
System.out.println("GEtting image....");
item = new ImageItem(null, image, 0, null);
form.append(item);
display.setCurrent(form);
} catch (IOException ioe) {
item.setLabel("Error1");
}
catch (Exception ioe) {
item.setLabel("Error1");
}
}
};
t.start(); // write post-action user code here
}
catch(Exception e){
System.out.println("Error3"+e);
}
}
}
How do I pass the URL to my innerthread class?
You have to declare the variable final or don't use a variable but a field in the class.
public class YourClass {
private String url;
public void yourMethod {
url = getURL(serverquery);
System.out.println("URl is "+serverquery);
item.setLabel(URL+item.getLabel());
Thread t = new Thread() {
public void run() {
item.setLabel(item.getLabel()+"6");
try {
Image image = loadImage(url); // using url
System.out.println("GEtting image....");
item = new ImageItem(null, image, 0, null);
form.append(item);
display.setCurrent(form);
} catch (IOException ioe) {
item.setLabel("Error1");
}
catch (Exception ioe) {
item.setLabel("Error1");
}
}
};
t.start(); // write post-action user code here
}
}
It should work if your URL is contained in a final reference. This means that the reference won't move. Consequently, you can't initialize it to null and then call getURL, you need to declare it at this point:
final String URL = getURL(serverquery);
I found that there are (at least) 2 major ways of doing this on whever your thread gets the information or recieves the information (in your case URL)
1) gets the informations:
what you want to do is keep a reference of the object containing the data you need (like URL) in your Thread, and when your ready the Thread gets the next item/URL to load.
public class MapTimer extends TimerTask{
public void run() {
...
}
private URLGenerator urlGenerator = null;
public MapTimer(URLGenerator urlGen){
...
}
This will give you the option to get the next URL when your thread is free (with a if(urlGen != null) of course)
2) Receives Information
Works better for cases where the thread is called only when the rest of the program wants to (user inputing data etc)
public class MapTimer extends TimerTask{
public void run() {
...
}
private URL urlToLoad = null;
public void setURL(URL urlToLoad){
...
//store and wake up thread
}
this way your thread recieve with a setter the data it needs to run, processes it then waits for the next data to be send to it (of course you need to be careful of thread issues like multiple calls etc.)
Hope this helps you
Jason
Just make the field a static variable belonging to the class and not any object instance of the class, like this:
public YourClass {
private static String url;
//...
}
Please note however that the static variable will be shared among all object instances of the class.

Categories

Resources