Multithreading does not work properly

Edit This message refers to the homework that I have for school, which dictates that I rely on swing to display my threads and logical flags to block.

My application creates a bunch of job objects, each of which contains a stream. Each work belongs to the being. A creature can have several tasks, but can only perform 1 of them at any time.

My thread uses 2 Boolean flags to determine if it should be run under the name "killFlag" and "goFlag". It denotes the creature to which it belongs as a "target." And each target has a logical "isWorking" to indicate whether it is busy with another task.

This is the thread that should run each task:

public void run() { long time = System.currentTimeMillis(); long startTime = time; long stopTime = time + 1000 * (long)( jobTime ); double duration = stopTime - time; synchronized (this.target) { while (this.target.isWorking) { status = 'w'; showStatus(); // hmmmmmmmm try { this.target.wait(); } catch (InterruptedException e) { } } this.target.isWorking = true; } while (time < stopTime && !killFlag) { try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { } if (goFlag) { status = 'p'; showStatus(); time += 100; this.showProgress.setValue((int)(((time - startTime) / duration) * 100)); } else { status = 'r'; showStatus(); } }//End While loop here showProgress.setValue(100); status = 'c'; showStatus(); synchronized (target) { target.isWorking = false; target.notifyAll(); } } 

At first I thought it was target.notifyAll() because it throws an IllegalMonitorStateException , but when I comment on this, the thread will create objects, but when I look at them in the GUI, 80% of them will be displayed as completely without any intervention from me, and the other 20% say the creature is busy.

At first, I thought it was because I dribble the kill flag too early, but when I moved or deleted it, the symptoms still persist. I'm turning around right now, and there are no programmers, haha, any advice you could give would mean peace.

To make sure that I provide enough information below, I use the methods that I use to interact with streams. The methods below work with a button that changes depending on whether the stream is working.

 public void showStatus() { //switch that changes status of button used to start / pause / display status of thread switch (this.status) { case 'r' : startJob.setEnabled(true); startJob.setText ("Run"); break; case 'p' : startJob.setEnabled(true); startJob.setText("Pause"); break; case 'w' : startJob.setEnabled(false); startJob.setText("Working"); break; case 'c' : startJob.setEnabled(false); startJob.setText("Job Complete"); break; } } private class theHandler implements ActionListener {//Listener for Button mentioned above public void actionPerformed (ActionEvent event) { if (event.getSource() == startJob) { if (goFlag) { goFlag = false; } else { goFlag = true; killFlag = false; } } else if (event.getSource() == stopJob) { if (killFlag) { //do nothing } else { killFlag = true; status = 'r'; } } } } 

It kills me, I dig to solve it in 6 hours.

Edit

After setting up my code based on MadProgrammer comment "target.notifyAll ()" fixed. Now the problem is that all threads are shown on the display as completed, even if the buttons instantly shift between states for a split second.

Edit

Many changes included below in response to comments

The following describes how I define a work class where killFlag, goFlag, etc. are defined.

  class Job extends Item implements SearchableByName, Runnable { int index; String name; int creature; double jobTime; Creature target; boolean goFlag = false; boolean killFlag = false; char status; JButton startJob; JButton stopJob; JProgressBar showProgress; JPanel p1; 

The following is the definition of the creature (target) in which boolean isWorking is located:

  class Creature extends Entity implements SearchableByName, SearchableByType, Runnable { int party; int empathy; int fear; int carryCapacity; Float age; Float height; Float weight; boolean isWorking = false; 

And in response to the comments, here is an image of how I show the threads: enter image description here

+8
java multithreading swing
source share
1 answer

Since some code is still missing, I first listed some assumptions; if any of these fail, my answer below may be wrong.

  • The run() method you specified is inside the Job class.
  • The Cancel button you are referring to is stopJob JButton

If you intend to reuse the same instance of Job to restart after the first run, your main problem is that your run() method exits. You have a while that checks !killFlag , but as soon as this loop ends (i.e., after the job is canceled and killFlag == true ), there is nothing that could make it return to the beginning and wait for the next goFlag == true to start working again. (Also, consider if the stopJob in your actionPerformed() method actionPerformed() do something with goFlag .)

On the other hand, if you intend to create a new instance of Job to represent a restartable job, then you did not specify the code that would do this.

I am a bit vague in my diagnosis above, to try and help you figure yourself out is the best way to find out. :) If you need more information, I can try to provide them, just LMK in the comment.

+2
source share

All Articles