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
Related
Together with some friends, I've tried to create a turnbased game. We have some issues regarding checking for when a user has their turn, while also keeping the GUI responsive, and also closing the thread we're using now when the game is closed. I wish to get some information on how to do this, but I'm not sure whether the problem is JavaFX-related, thread-related or both.
I've tried to search as much as I can, but simply couldn't find exactly what I'm looking for, even though I believe it is quite simple. Right now, we have a thread running a loop when you click a button to check whether or not it is your turn. When it isn't your turn, we wish to disable some user input, so I'm not sure if we actually need a thread, other than to keep the responsiveness.
I've also tried implementing a class extending Thread, but this only seemed to make the problems worse by either starting a new thread each time it wasn't the players turn, or freezing the GUI if I put the loop outside of the thread.
public void refreshButtonPressed(){
try{
refreshButton.setDisable(true);
Thread pollThread = new Thread(() -> {
System.out.println("Thread started"); //Stop being able to start more threads
int user_id = 0;
String gamePin = "xxxxxx";
while (!GameConnection.yourTurn(user_id, Context.getContext().getGamePin())){ //This method checks the database if it is your turn
try{
Thread.sleep(5000); //So we don't flood the database
}
catch (InterruptedException e){
System.out.println("Interrupted");
break;
}
//If we close the game, stop the thread/while loop.
if (TurnPolling.closedGame){
break;
}
}
playerButton.setDisable(false);
refreshButton.setDisable(false);
refreshButton.setText("Refresh");
System.out.println("Thread ended");
});
pollThread.start();
}catch (Exception e){
e.printStackTrace();
}
}
And in the controller for the gameScreen.fxml file (Not the main screen, but one loaded via login screens and the Main extending Application).
public void initialize(URL location, ResourceBundle resources) {
playerButton.setDisable(!GameConnection.yourTurn(user_id, gameTurn));
myStage.setOnCloseRequest(event -> TurnPolling.closedGame = true);
}
Right now, the TurnPolling class only has the public static boolean closedGame, so as not to keep this in the controller. The last line setting the closedGame = true actually gives me a NullPointerException, which may be because the Stage isn't initialized yet, when I do this in the initialize() method?
I would wish to enable the players buttons only when it is their turn, as well as closing the thread (if needed) when the gameScreen closes. Right now, you have to click a button to check if it is your turn, which again checks every five seconds, and it won't stop when you close the game.`
Please tell me if you need more code or clarification, this is my first big project, so I don't really know how much to put here. I know this isn't working code, but it's as much as I can do without it feeling like cluttering. Thank you for any answers!
First, it is important to remember that it is not permitted to alter JavaFX nodes in any thread other than the JavaFX application thread. So, your thread would need to move these lines:
playerButton.setDisable(false);
refreshButton.setDisable(false);
refreshButton.setText("Refresh");
into a Runnable which is passed to Platform.runLater:
Platform.runLater(() -> {
playerButton.setDisable(false);
refreshButton.setDisable(false);
refreshButton.setText("Refresh");
});
Note that changes to your TurnPolling.closedGame field in one thread may not be visible in another thread, unless it’s declared volatile. From the Java Language Specification:
For example, in the following (broken) code fragment, assume that this.done is a non-volatile boolean field:
while (!this.done)
Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done.
Using Task and Service
JavaFX provides a cleaner solution to all this: Task and Service.
A Service creates Tasks. A Service has a bindable value property, which is always equal to the value of the most recently created Task. You can bind your button properties to the Service’s value property:
int user_id = 0;
Service<Boolean> turnPollService = new Service<Boolean>() {
#Override
protected Task<Boolean> createTask() {
return new Task<Boolean>() {
#Override
protected Boolean call()
throws InterruptedException {
updateValue(true);
String gamePin = Context.getContext().getGamePin();
while (!GameConnection.yourTurn(user_id, gamePin)) {
Thread.sleep(5000);
if (TurnPolling.closedGame){
break;
}
}
return false;
}
};
}
};
playerButton.disableProperty().bind(turnPollService.valueProperty());
refreshButton.disableProperty().bind(turnPollService.valueProperty());
refreshButton.textProperty().bind(
Bindings.when(
turnPollService.valueProperty().isEqualTo(true))
.then("Waiting for your turn\u2026")
.otherwise("Refresh"));
When the player’s turn is finished, you would call turnPollService.restart();.
Whether you use a Service, or just use Platform.runLater, you still need to make TurnPolling.closedGame thread-safe, either by making it volatile, or by enclosing all accesses to it in synchronized blocks (or Lock guards).
Is there a way to safely and immediately stop the execution of a Thread in Java? Especially, if the logic inside the run() method of the Runnable implementation executes only a single iteration and does not regularly check for any flag that tells it to stop?
I am building a Web Application, using which a user can translate the contents of an entire document from one language to another.
Assuming the documents are extra-large, and subsequently assuming each translation is going to take a long time (say 20-25 minutes), my application creates a separate Thread for each translation that is initiated by its users. A user can see a list of active translations and decide to stop a particular translation job if he/she wishes so.
This is my Translator.java
public class Translator {
public void translate(File file, String sourceLanguage, String targetLanguage) {
//Translation happens here
//.......
//Translation ends and a new File is created.
}
}
I have created a TranslatorRunnable class which implements the Runnable interface as follows:
public class TranslatorRunnable implements Runnable {
private File document;
private String sourceLanguage;
private String targetLanguage;
public TranslatorRunnable(File document, String sourceLanguage, String targetLanguage) {
this.document = document;
this.sourceLanguage = sourceLanguage;
this.targetLanguage = targetLanguage;
}
public void run() {
// TODO Auto-generated method stub
Translator translator = new Translator();
translator.translate(this.document, this.sourceLanguage, this.targetLanguage);
System.out.println("Translator thread is finished.");
}
}
I'm creating the thread for translating a document from an outer class like this:
TranslatorRunnable tRunnable = new TranslatorRunnable(document, "ENGLISH", "FRENCH");
Thread t = new Thread(tRunnable);
t.start();
Now my problem is how do I stop a translation process (essentially a Thread) when the user clicks on "Stop" in the GUI?
I have read a few posts on StackOverflow as well as on other sites, which tell me to have a volatile boolean flag inside the Runnable implementation, which I should check on regularly from inside the run() method and decide when to stop. See this post
This doesn't work for me as the run() method is just calling the Translator.translate() method, which itself is going to take a long time. I have no option here.
The next thing I read is to use ExecutorService and use its shutDownAll() method. But even here, I'd have to handle InterruptedException somewhere regularly within my code. This, is again out of the option. Referred this documentation of the ExecutorService class.
I know I cannot use Thread.stop() as it is deprecated and may cause issues with objects that are commonly used by all threads.
What options do I have?
Is my requirement really feasible without substantial changes to my design? If yes, please tell me how.
If it is absolutely necessary for me to change the design, could anyone tell me what is the best approach I can take?
Thanks,
Sriram
Is there a way to safely and immediately stop the execution of a Thread in Java?
No. each thread is reponsible to periodically check if it has been interrupted to exit as soon as possible
if (Thread.currentThread().isInterrupted() ) {
// release resources. finish quickly what it was doing
}
if you want a more responsive application, you have to change the logic (for example divide each job in smaller batches) so each thread does this checking more often than every 20-25 minutes
If you are the one that created the Translator class what's stopping you from adding some kind of value inside the function that is checked periodically and if needed stops reading the lines from file something like this
public static List<String> readFile(String filename)
{
List<String> records = new ArrayList<>();
try
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ((line = reader.readLine()) != null)
{
String[] split = line.split("\\s+");
records.addAll(Arrays.asList(split));
if (needsToStop) {
break; //Or throw exception
}
}
reader.close();
return records;
}
catch (Exception e)
{
System.err.format("Exception occurred trying to read '%s'.", filename);
e.printStackTrace();
return null;
}
}
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.
Is there a JavaFX equivalent to the Java SwingWorker class?
I am aware of the JavaFX Task but with that you can only publish String messages or a progress. I just want to call a method in the GUI thread like I would have done with the SwingWorker (by publishing messages of an arbitrary type).
Heres is an example of what I mean:
class PrimeNumbersTask extends
SwingWorker<List<Integer>, Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}
#Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
setProgress(100 * numbers.size() / numbersToFind);
}
}
return numbers;
}
#Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "\n"); // HERE: execute in GUI thread
}
}
}
Solution
Thank you very much for your answers. The solution I was searching for, is to use Platform.runLater(Runnable guiUpdater).
I would rewrite your SwingWorker as follows:
class PrimeNumbersTask extends Task<List<Integer>> {
PrimeNumbersTask(TextArea textArea, int numbersToFind) {
// initialize
}
#Override
protected List<Integer> call() throws Exception {
while (!enough && !isCancelled()) {
number = nextPrimeNumber();
updateMessage(Integer.toString(number));
updateProgress(numbers.size(), numbersToFind);
}
return numbers;
}
}
Usage:
TextArea textArea = new TextArea();
PrimeNumbersTask task = new PrimeNumbersTask(numbersToFind);
task.messageProperty().addListener((w, o, n)->textArea.appendText(n + "\n"));
new Thread(task).start(); // which would actually start task on a new thread
Explanation:
Yes, we do not have a publish() method as the SwingWorker does in JavaFX, but in your case using the updateMessage() is sufficient, as we can register a listener to this property and append a new line every time the message is updated.
If this is not enough, you can always use Platform.runLater() to schedule GUI updates. If you are doing too many GUI updates and the GUI Thread is being slowed down, you can use the following idiom: Throttling javafx gui updates
Apart from the updateMessage method where you can only pass strings, there is the updateValue method where you can pass a whole object, so I believe you can use that in a similar manner. This approach is described in the "A Task Which Returns Partial Results" section of the Task documentation. Another approach is the Platform.runLater() approach mentioned also in other answer.
Note that an important difference between these approaches, is that the first one is coalescing the results, which means that for multiple frequent updateValue calls some may be omitted in order to protect flooding the FX thread.
On the other hand, the Platform.runLater approach will send all the interim results, but due to the danger of flooding the FX thread if you have high frequency updates, some additional effort may be needed to manually avoid it like #eckig suggested in his answer which points to Throttling javafx gui updates
Don't ever use SwingWorker. This piece of code in the SwingWorker.java source should be enough of an argument to not use it:
private static final int MAX_WORKER_THREADS = 10;
Instead get yourself familiar with Executor and the services that come along with it.
It has nothing to do with JavaFX, it's just plain Java. However, your question was related to JavaFX. Here's an example about how to Update UI in JavaFX Application Thread using Platform.runLater().
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();
}