How to take object from BlockingQueue? - java

I have a class X, classMachine, class Z, all of them are Threads. When Machine threads are initialized, they are put on a BlockingQueue firstQueue. Inside machines' run method there is a while loop which checks if its boolean variable should be true or false. When it is true, machine should be put on BlockingQueue secondQueue
secondQueue.put(this);
and Z class can take it from there. If machine thread returns false, class X can take machine from firstQueue and work on it.
Now, my question is: when boolean is true, is it possible to make Machine take itself from firstQueue?
PS.I know that the question might be unclearly asked, but I don't know how to form it properly. If anyone knows to make it better, please correct it.
EDIT.
Code samples.
Here is a part from class that starts all the threads, all the queues are initialized of course.
public class Machine implements Runnable{
private final BlockingQueue firstQueue;
private final BlockingQueue secondQueue;
boolean broken;
public Machine(...){...}
public void run() {
while(true){
//use Rand (min=0, max=1) and define if(random==1)broken=true else broken=false
if(broken==true){
Machine multi = fistQueue.take(this);//here is problem!!!!!
secondQueue.put(this);
}
}
}...}
and part form class that starts the threads
//machines should have an ability to take themselves from queue when broken==true, and then put on secondQueue
BlockingQueue<Machine> firstQueue = new ArrayBlockingQueue<Machine>(10);
service=Executors.newFixedThreadPool(10);
for(int k=0; k < 10; k++){
Machine M= new Machine(secondQueue, k);
firstQueue.add(M);
service.submit(M);
}
//X can take machines from firstQueue, and work on them if broken==false
Thread XThread = new Thread(new X(firstQueue));
XThread.start();
//takes machines form secondQueue
Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();
EDIT2
public class X implements Runnable(){
//fields, constructor
public void run() {
while(true){
machine=machines.take();
if(machine.broken==true){
//leave this machine (it should be on , and take other which is fine_
}
while(machine.broken==false){
machine.pass(record); // (Record record=new Record(task, result field);
//do Your thing
}
if(result==initialResultFromX){
//means it got broken while working and needs to take a new machine
}
}...
}

First of, this answer aims to help improve the design of the solution, which in turn might answer the actual question. However, if OP is happy with the current design, I believe the question can be answered by removing the following line:
Machine multi = fistQueue.take(this);
So,
Is it possible to make Machine take itself from firstQueue?
There is no method to directly get an object inside the queue without removing it (As stated in the comments, the machine should not be removed from the first queue). Because you can access the instance of the machine by using this, secondQueue.put(this) would suffice in adding the Machine to the second queue.
I might be interpreting your design wrong, but it seems to me that each Machine has a state. This state depends whether or not the Machine can or cannot execute whatever it must execute. If this is true, I believe it isn't wise to keep the handling of state changes in the machine itself(adding/removing itself to different executing queues).
You need an abstraction of some sort. Lets called this your StateMachine. The StateMachine creates, manages and handles state changes of each Machine, by implementing some listening interface. This will allow each machine to report any events or problems to the StateMachine. The StateMachine can then determine how to handle events.
I'll try to explain by example. Here is the interface that the StateMachine will implement:
public interface BrokenListener {
public void onBrokenEvent(Object machine);
}
This allows communications between the StateMachine and each Machine. However, this requires an instance of the StateMachine to be passed to each machine instead of the queues.
for(int k=0; k < 10; k++){
Machine m = new Machine(this); //where this is the StateMachine
firstQueue.add(m);
}
Once a Machines state changes from broken == false to broken == true, the onBrokenEvent() can be called.
public class Machine {
/* The listener */
private BrokenListener listener;
private boolean broken = false;
public Machine(BrokenListener listener) {
this.listener = listener;
}
/* When the state of the machine changes */
public void setBroken(boolean broken) {
this.broken = broken;
if (this.broken) {
//Here we pass the current Machine to the StateMachine. How the event is handled should not be up to the machine.
this.listener.onBrokenEvent(this);
}
}
}
Here is the StateMachine:
public class StateMachine implements BrokenListener {
#Override
public void onBrokenEvent(Object machine) {
if (machine instanceof Machine) {
second.add((Machine) machine);
}
}
}
As you can see, when the state machine implements the onBrokenEvent method. When this method is called by the Machine, it can be added to the second queue for processing.
I assume the X and Y classes will do the processing, so you still need to pass the queues to them.
Thread XThread = new Thread(new X(firstQueue));
XThread.start();
Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();
What makes this nice is, it keeps the logic used for handling state changes out of the Machine.
Feel free to ask any questions.

Related

Thread problem in Java: two threads with same priority should have no "order" right?

I am practicing how to use Thread in Java. currently I am trying to proof that how two separate threads dealing with shared variables. I created a class:
public class Prac{
int z = 0;
public void foo(int i){
this.z = i;
System.out.println(Thread.currentThread().getName() + " updated z to " + z);
System.out.println("current z is " + this.z);
}
public static void main(String[] args){
Prac p = new Prac();
Thread t1 = new Thread(new MyThread1(p));
Thread t2 = new Thread(new MyThread2(p));
t1.start();
t2.start();
}
}
and also two threads:
public class MyThread1 implements Runnable{
Prac p = null;
public MyThread1 (Prac p){
this.p=p;
}
public void run(){
p.foo(1);
}
}
public class MyThread2 implements Runnable{
Prac p = null;
public MyThread2 (Prac p){
this.p=p;
}
public void run(){
p.foo(2);
}
}
I thought the final value of z should be sometimes 1, sometimes 2. However, the final will always be 2. and if I move t2.start() before t1.start(), the final will always be 1. I thought there should be no specific order of the execution of the two threads with the same priority, right? but why the outcome is not what I expected please?
Thanks
I am trying to prove...
The behavior of unsynchronized threads in Java (and in most other programming languages) is deliberately left undefined. The reason for that is, there is diversity in the design of different multi-processor systems, and leaving certain behaviors undefined allows the implementors to do things in the most efficient way on any given hardware platform and OS.
But, by giving Java implementors freedom to do things in the most efficient way, they took away your ability to prove anything about threads through testing. A program that behaves in the same way every time you run it on a certain machine on a certain day may behave differently on a different machine, on a different OS, on a different version of the same OS, in a different JVM, on a different day, etc.
If you want to guarantee any particular outcome of a multi-threaded program, the only way you can do it is by using documented synchronization mechanisms and, by inferring how your program will behave based on the guarantees, spelled out in Chapter 17 of the Java Language Specification, about what those synchronization mechanisms will do.

Swing Worker threads stop executing code unexpectedly

I am trying to create a platform for testing mutual exclusion algorithms using Swing. My intent is to display servers and messages being sent between them in the GUI. I also want to display a critical section which shows which servers are currently accessing it. I am using a threadpool that executes SwingWorker threads to deploy the servers which load a user selected mutex algorithm.
The program runs as expected until I try to implement the message displays. To display an arrow for each message I've extended SwingWorker, UIArrowThread, to add a JLabel that draws an arrow from the source server to the target. This thread waits for 1 second before removing the JLabel. This seems to be working fine when I explicitly create one or more of these messages(I've also created a test platform where I can create specific messages).
The problem comes when I try to integrate this SwingWorker thread into the program. When the algorithm is started, each server attempts to access the critical section and sends its requests to each of the other servers. This should invoke UIArrowThread but it appears that only some servers actually create the thread.
public void sendMsg(int destId, Object ... objects) {
comm.sendMsg(destId, objects);
try{
UIArrowThread a = new UIArrowThread(AlgorithmSimulatorUI.jlp,
objects[0].toString(),
comm.getMyId(),
destId);
AlgorithmSimulatorUI.threadPool.execute(a);
} catch (Exception exc){
System.err.println(exc);
}
}
Some of the servers just seem to stop executing just before instantiating UIArrowThread and ends up creating a deadlock. Any servers that do make it passed that point work normal and the GUI displays as it should be. I have testing with logging just before UIArrowThread is called and in its constructor. The threads that look like they stop executing never make the log call in the constructor. I'm pretty stumped on why this would be happening.
public class UIArrowThread extends SwingWorker<Integer, String>{
JLayeredPane jlp;
String type;
int source;
int target;
Point start;
Point end;
Point[] points;
int quadrant;
public UIArrowThread(JLayeredPane jlp, String msg_type, int source,
int target){
this.jlp = jlp;
this.type = msg_type;
this.source = source;
this.target = target;
this.points = getPoints();
this.start = points[0];
this.end = points[1];
}
#Override
protected Integer doInBackground(){
Point lblPoint = getLabelCoordinates(points);
ArrowLabel arrow = new ArrowLabel(type, 1, 2, jlp, points, quadrant);
if (quadrant < 5){
arrow.setBounds(lblPoint.x, lblPoint.y, abs(start.x - end.x),
abs(start.y - end.y));
} else if (quadrant < 7){
arrow.setBounds(lblPoint.x, lblPoint.y, 100, abs(start.y - end.y));
} else {
arrow.setBounds(lblPoint.x, lblPoint.y, abs(start.x - end.x), 100);
}
jlp.add(arrow);
String openHTML = "<html><font color='red',size=12>";
String closeHTML = "</font></html>";
arrow.setText(openHTML + type + closeHTML);
arrow.setHorizontalTextPosition(JLabel.CENTER);
arrow.setVerticalTextPosition(JLabel.CENTER);
jlp.repaint();
try{
Thread.sleep(arrow.lifespan);
} catch (Exception exc){
System.err.println(exc);
} finally {
jlp.remove(arrow);
}
jlp.repaint();
return 1;
}
I've added what I feel would be the relevant part of code for this problem. As mentioned above, if I remove the UIArrowThread, the program will run correctly.
I tried a few more approaches that still produce the same results including doing the work in process() instead of doInBackground(), and having the ArrowLabel remove itself from the GUI instead of UIArrowThread doing the removal.
Update:
I was able to get the UI working as intended but still not really sure what the original issue is. The program has a messaging queue that displays the messages from servers in a textPane so I figured I'd update the UI with the arrow labels here. It was not neccessary to alter any of the existing code for ArrowLabel or UIArrowThread.
Your fragment suggests that you are updating a Swing component, ArrowLabel, in the doInBackground() method of a SwingWorker. This violates the Swing single-thread rule. Instead, query the servers in the background, publish() interim results, and process() them on the EDT, as shown in the examples examined here. The exact formulation of "the type used for carrying out intermediate results by this SwingWorker's publish and process methods" will depend on your use case. As a concrete example, this TableSwingWorker extends SwingWorker<MyTableModel, RowData>, publishing instances of RowData used to update a TableModel

Visibility in Java global exception handler

I'm writing a program in Java that will allow a person to input data into a form as jobs for a help desk. The submitted form is then used to create a helpRequest object which is entered into a generic Queue for storage in a binary file. However, the onus of the project (it's a school assignment) is to make the program failsoft using exceptions. One specific stipulation of the program is that it must handle any situation where it cannot continue by attempting to save the current helpRequest queue before terminating "gracefully". I've got all of this set up in code, but when the handler runs (by a division by zero in my test), the program hangs as soon as it tries to do anything with the helpQueue.
I've tried looking up Java global variables and global exception handlers, but nothing seems to address the topic of using a structure or variable from another/the throwing class.
Here is the code for the handler. I have helpQueue declared as public and static in the throwing class HelpDeskForm, and NetBeans accepts all the code I have here. The induced exception occurs after the queue has been worked with.
public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {
BinaryOutputFile emergencyOutput;
public void uncaughtException(Thread t, Throwable e) {
Frame f = new Frame();
JOptionPane.showMessageDialog(f, "Program error. Please select a file for queue output.");
emergencyOutput = new BinaryOutputFile();
while(!HelpDeskForm.helpQueue.isEmpty())
emergencyOutput.writeObject(HelpDeskForm.helpQueue.remove());
emergencyOutput.close();
System.exit(1);
}
}
Rather than a specific solution to my issue, I'd appreciate it if someone could explain why helpQueue is seemingly not actually visible/usable in this exception handler, or what I'm doing horribly wrong.
EDIT: I didn't want to overcomplicate my explanation, but here is the HelpDeskForm code up until my division by zero exception.
public class HelpDeskForm {
BinaryDataFile input;
BinaryOutputFile output;
CheckedForm c;
helpRequest r;
public static Queue<helpRequest> helpQueue;
int inputSize;
public HelpDeskForm() {
GlobalExceptionHandler h = new GlobalExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(h);
input = new BinaryDataFile();
inputSize = input.readInt();
for(int i = 0; i < inputSize; i++) {
helpQueue.add((helpRequest)input.readObject());
}
input.close();
int y = 0;
int z = 2;
z = z/y;
... // GUI code follows
}
}
HelpDeskForm seems to lack initialization for queue being used, so NPE is inevitable. Try to add initialization to declaration:
public static Queue<helpRequest> helpQueue = new ArrayBlockingQueue<helpRequest>(100);
Plus, for the posted code, it would be logical to add volatile keyword to queue declaration:
public static volatile BlockingQueue<helpRequest> helpQueue;
public void createQueue() {
// make sure createQueue() is called at the very beginning of your app,
// somewhere in main()
helpQueue = new ArrayBlockingQueue...
}
This way all other threads, if any, will see correct reference to the queue, and thread safety of BlockingQueue guarantees correct visibility of its' contents.

Java: Getting ExecutorService to produce repeatable behavior?

I have been trying to parallelize a portion of a method within my code (as shown in the Example class's function_to_parallelize(...) method). I have examined the executor framework and found that Futures & Callables can be used to create several worker threads that will ultimately return values. However, the online examples often shown with the executor framework are very simple and none of them appear to suffer my particular case of requiring methods in the class that contains that bit of code I'm trying to parallelize. As per one Stackoverflow thread, I've managed to write an external class that implements Callable called Solver that implements that method call() and set up the executor framework as shown in the method function_to_parallelize(...). Some of the computation that would occur in each worker thread requires methods *subroutine_A(...)* that operate on the data members of the Example class (and further, some of these subroutines make use of random numbers for various sampling functions).
My issue is while my program executes and produces results (sometimes accurate, sometimes not), every time I run it the results of the combined computation of the various worker threads is different. I figured it must be a shared memory problem, so I input into the Solver constructor copies of every data member of the Example class, including the utility that contained the Random rng. Further, I copied the subroutines that I require even directly into the Solver class (even though it's able to call those methods from Example without this). Why would I be getting different values each time? Is there something I need to implement, such as locking mechanisms or synchronization?
Alternatively, is there a simpler way to inject some parallelization into that method? Rewriting the "Example" class or drastically changing my class structuring is not an option as I need it in its current form for a variety of other aspects of my software/system.
Below is my code vignette (well, it's an incredibly abstracted/reduced form so as to show you basic structure and the target area, even if it's a bit longer than usual vignettes):
public class Tools{
Random rng;
public Tools(Random rng){
this.rng = rng;
}...
}
public class Solver implements Callable<Tuple>{
public Tools toolkit;
public Item W;
public Item v;
Item input;
double param;
public Solver(Item input, double param, Item W, Item v, Tools toolkit){
this.input = input;
this.param = param;
//...so on & so forth for rest of arguments
}
public Item call() throws Exception {
//does computation that utilizes the data members W, v
//and calls some methods housed in the "toolkit" object
}
public Item subroutine_A(Item in){....}
public Item subroutine_B(Item in){....}
}
public class Example{
private static final int NTHREDS = 4;
public Tools toolkit;
public Item W;
public Item v;
public Example(...,Tools toolkit...){
this.toolkit = toolkit; ...
}
public Item subroutine_A(Item in){
// some of its internal computation involves sampling & random # generation using
// a call to toolkit, which houses functions that use the initialize Random rng
...
}
public Item subroutine_B(Item in){....}
public void function_to_parallelize(Item input, double param,...){
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
List<Future<Tuple>> list = new ArrayList<Future<Tuple>>();
while(some_stopping_condition){
// extract subset of input and feed into Solver constructor below
Callable<Tuple> worker = new Solver(input, param, W, v, toolkit);
Future<Tuple> submit = executor.submit(worker);
list.add(submit);
}
for(Future<Tuple> future : list){
try {
Item out = future.get();
// update W via some operation using "out" (like multiplying matrices for example)
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown(); // properly terminate the threadpool
}
}
ADDENDUM: While flob's answer below did address a problem with my vignette/code (you should make sure that you are setting your code up to wait for all threads to catch up with .await()), the issue did not go away after I made this correction. It turns out that the problem lies in how Random works with threads. In essence, the threads are scheduled in various orders (via the OS/scheduler) and hence will not repeat the order in which they are executed every run of the program to ensure that a purely deterministic result is obtained. I examined the thread-safe version of Random (and used it to gain a bit more efficiency) but alas it does not allow you to set the seed. However, I highly recommend those who are looking to incorporate random computations within their thread workers to use this as the RNG for multi-threaded work.
The problem I see is you don't wait for all the tasks to finish before updating W and because of that some of the Callable instances will get the updated W instead of the one you were expecting
At this point W is updated even if not all tasks have finished
Blockquote
// update W via some operation using "out" (like multiplying matrices for example)
The tasks that are not finished will take the W updated above instead the one you expect
A quick solution (if you know how many Solver tasks you'll have) would be to use a CountDownLatch in order to see when all the tasks have finished:
public void function_to_parallelize(Item input, double param,...){
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
List<Future<Tuple>> list = new ArrayList<Future<Tuple>>();
CountDownLatch latch = new CountDownLatch(<number_of_tasks_created_in_next_loop>);
while(some_stopping_condition){
// extract subset of input and feed into Solver constructor below
Callable<Tuple> worker = new Solver(input, param, W, v, toolkit,latch);
Future<Tuple> submit = executor.submit(worker);
list.add(submit);
}
latch.await();
for(Future<Tuple> future : list){
try {
Item out = future.get();
// update W via some operation using "out" (like multiplying matrices for example)
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown(); // properly terminate the threadpool
}
then in the Solver class you have to decrement the latch when call method ends:
public Item call() throws Exception {
//does computation that utilizes the data members W, v
//and calls some methods housed in the "toolkit" object
latch.countDown();
}

Java Multithreading large arrays access

My main class, generates multiple threads based on some rules. (20-40 threads live for long time).
Each thread create several threads (short time ) --> I am using executer for this one.
I need to work on Multi dimension arrays in the short time threads --> I wrote it like it is in the code below --> but I think that it is not efficient since I pass it so many times to so many threads / tasks --. I tried to access it directly from the threads (by declaring it as public --> no success) --> will be happy to get comments / advices on how to improve it.
I also look at next step to return a 1 dimension array as a result (which might be better just to update it at the Assetfactory class ) --> and I am not sure how to.
please see the code below.
thanks
Paz
import java.util.concurrent.*;
import java.util.logging.Level;
public class AssetFactory implements Runnable{
private volatile boolean stop = false;
private volatile String feed ;
private double[][][] PeriodRates= new double[10][500][4];
private String TimeStr,Bid,periodicalRateIndicator;
private final BlockingQueue<String> workQueue;
ExecutorService IndicatorPool = Executors.newCachedThreadPool();
public AssetFactory(BlockingQueue<String> workQueue) {
this.workQueue = workQueue;
}
#Override
public void run(){
while (!stop) {
try{
feed = workQueue.take();
periodicalRateIndicator = CheckPeriod(TimeStr, Bid) ;
if (periodicalRateIndicator.length() >0) {
IndicatorPool.submit(new CalcMvg(periodicalRateIndicator,PeriodRates));
}
}
if ("Stop".equals(feed)) {
stop = true ;
}
} // try
catch (InterruptedException ex) {
logger.log(Level.SEVERE, null, ex);
stop = true;
}
} // while
} // run
Here is the CalcMVG class
public class CalcMvg implements Runnable {
private double [][][] PeriodRates = new double[10][500][4];
public CalcMvg(String Periods, double[][][] PeriodRates) {
System.out.println(Periods);
this.PeriodRates = PeriodRates ;
}
#Override
public void run(){
try{
// do some work with the data of PeriodRates array e.g. print it (no changes to array
System.out.println(PeriodRates[1][1][1]);
}
catch (Exception ex){
System.out.println(Thread.currentThread().getName() + ex.getMessage());
logger.log(Level.SEVERE, null, ex);
}
}//run
} // mvg class
There are several things going on here which seem to be wrong, but it is hard to give a good answer with the limited amount of code presented.
First the actual coding issues:
There is no need to define a variable as volatile if only one thread ever accesses it (stop, feed)
You should declare variables that are only used in a local context (run method) locally in that function and not globally for the whole instance (almost all variables). This allows the JIT to do various optimizations.
The InterruptedException should terminate the thread. Because it is thrown as a request to terminate the thread's work.
In your code example the workQueue doesn't seem to do anything but to put the threads to sleep or stop them. Why doesn't it just immediately feed the actual worker-threads with the required workload?
And then the code structure issues:
You use threads to feed threads with work. This is inefficient, as you only have a limited amount of cores that can actually do the work. As the execution order of threads is undefined, it is likely that the IndicatorPool is either mostly idle or overfilling with tasks that have not yet been done.
If you have a finite set of work to be done, the ExecutorCompletionService might be helpful for your task.
I think you will gain the best speed increase by redesigning the code structure. Imagine the following (assuming that I understood your question correctly):
There is a blocking queue of tasks that is fed by some data source (e.g. file-stream, network).
A set of worker-threads equal to the amount of cores is waiting on that data source for input, which is then processed and put into a completion queue.
A specific data set is the "terminator" for your work (e.g. "null"). If a thread encounters this terminator, it finishes it's loop and shuts down.
Now the following holds true for this construct:
Case 1: The data source is the bottle-neck. It cannot be speed-up by using multiple threads, as your harddisk/network won't work faster if you ask more often.
Case 2: The processing power on your machine is the bottle neck, as you cannot process more data than the worker threads/cores on your machine can handle.
In both cases the conclusion is, that the worker threads need to be the ones that seek for new data as soon as they are ready to process it. As either they need to be put on hold or they need to throttle the incoming data. This will ensure maximum throughput.
If all worker threads have terminated, the work is done. This can be i.E. tracked through the use of a CyclicBarrier or Phaser class.
Pseudo-code for the worker threads:
public void run() {
DataType e;
try {
while ((e = dataSource.next()) != null) {
process(e);
}
barrier.await();
} catch (InterruptedException ex) {
}
}
I hope this is helpful on your case.
Passing the array as an argument to the constructor is a reasonable approach, although unless you intend to copy the array it isn't necessary to initialize PeriodRates with a large array. It seems wasteful to allocate a large block of memory and then reassign its only reference straight away in the constructor. I would initialize it like this:
private final double [][][] PeriodRates;
public CalcMvg(String Periods, double[][][] PeriodRates) {
System.out.println(Periods);
this.PeriodRates = PeriodRates;
}
The other option is to define CalcMvg as an inner class of AssetFactory and declare PeriodRate as final. This would allow instances of CalcMvg to access PeriodRate in the outer instance of AssetFactory.
Returning the result is more difficult since it involves publishing the result across threads. One way to do this is to use synchronized methods:
private double[] result = null;
private synchronized void setResult(double[] result) {
this.result = result;
}
public synchronized double[] getResult() {
if (result == null) {
throw new RuntimeException("Result has not been initialized for this instance: " + this);
}
return result;
}
There are more advanced multi-threading concepts available in the Java libraries, e.g. Future, that might be appropriate in this case.
Regarding your concerns about the number of threads, allowing a library class to manage the allocation of work to a thread pool might solve this concern. Something like an Executor might help with this.

Categories

Resources