3

i'm developing an app in java that launches some threads that do some jobs and update a JTable with a JProgressBar. I develope a JPopupMenu on the JTable that has some JMenuItem:

  • Pause
  • Stop
  • Cancel
  • Resume

So i want to be able to do it.

When user add new thread in JTable i save the thread in a ArrayList<Thread>, so i have to implement

stop.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {

            }
        });

and the other..

so i try , with the hypothesis that i have the index of current thread:

Thread t = working.get(selectedThread); //where working is my `ArrayList<Thread>`
t.interrupt();

but nothing.. it continue working... so i try:

try {
                        working.get(actualRow).wait();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(PannelloRicerca.class.getName()).log(Level.SEVERE, null, ex);
                    }

but it get me IllegalStateMonitorException on wait(), so i don't know how to do.. can someone help me?

Jayyrus
  • 12,961
  • 41
  • 132
  • 214
  • You need to have lock of working.get(actualRow) object in order to invoke wait. That is the reason you are getting IllegalStateMonitorException. wait can be called from synchronized block or synchronized method. Instead of using interrupt call on thread, send notification to thread by setting some variable of thread. And in thread use this value to stop execution – Delta Mar 23 '12 at 02:56

2 Answers2

2

The Thread.interrupt() call only sets the interrupt bit on the Thread and it causes any wait or sleep calls to throw InterruptedException. It does not cancel the execution of the thread like many expect.

You can test for the interrupt bit in a thread like this:

while (!Thread.currentThread().isInterrupted()) {
   ...
}

A typical way for folks to stop a thread is to have an AtomicBoolean (or volatile boolean) and do something like:

AtomicBoolean running = new AtomicBoolean(true);
while (running.set()) {
    ...
}

...
// then in the other thread (like the main thread) you stop the thread by:
runner.set(false);

You are getting the IllegalStateMonitorException because you are calling wait without being inside of a synchronized block for the object you are waiting on. You need to do something like:

Thread t = working.get(actualRow);
synchronized (t) {
    t.wait();
}

Although I'm not sure that's what you want. Maybe you want to join on the thread which waits for it to finish?

   working.get(actualRow).join();
Gray
  • 115,027
  • 24
  • 293
  • 354
  • the problem is that the jobs of my i-thread(i means that there are many thread that working togheter) is to parse some html page inside two innested loop. so where i can put your while condition? – Jayyrus Mar 22 '12 at 23:56
  • What's the goal @Jack? Are you trying to stop the processing of this html page? You can obviously do an if every so often. – Gray Mar 22 '12 at 23:59
  • 1
    no.. i didn't explain good.. i have a Jpanel in which i have a JTable and a JComboBox. users can select an object into JCombobox then clicking on a JButton can launch a thread. This thread first update JTable adding a row that inside has some text and a JProgressBar ( manipulating by the thread just launched), then parse many html page changing, on every page, some text and the value of JProgressBar inside the row just inserted in JTable. Users can launch many thread and ,clicking with right button of the mouse on a row of JTable show a JPopupMenu described in my post. – Jayyrus Mar 23 '12 at 00:09
  • 1
    With JPopupMenu users can stop, pause, cancel an resume the thread associated with the row clicked. – Jayyrus Mar 23 '12 at 00:09
  • @Jack Is the thread just sitting there or is it waiting on some condition. If it is waiting then you should catch `InterruptedException` and then exit the thread. Are you maybe catching and ignoring one of those? – Gray Mar 23 '12 at 00:14
  • yes.. at the end of loops it stops normally.. but i want to let users to stop, pause , etc. when he want to speed another – Jayyrus Mar 23 '12 at 00:45
1

The IllegalStateMonitorException is because a thread can only wait in an object it it 'owns' (I don't remember if it is the right term) it.

You need to synchronize by the same object first, in order to ensure that nobody else is already waiting on this object.

 synchronize (working.get(actualRow)) {
   working.get(actualRow).wait(); 
 }
SJuan76
  • 24,532
  • 6
  • 47
  • 87
  • sorry.. it blocks all the GUI – Jayyrus Mar 23 '12 at 00:49
  • Only one of your threads can be in the synchronized section of a given object. If you do a synchronize in an object an another thread tries to synchronize with the same object, the second one will stop until the first one leaves the synchronized block. This is exactly the purpose of synchronized. If you want just to do a wait without blocking issues, synchronize each thread using a different object (a freshly created object, or even the very own Thread object). – SJuan76 Mar 23 '12 at 08:58