Maher Hejazi
Maher Hejazi

Reputation: 33

Threads stopping, suspending, and resuming

I'm writing a code that involves JFrame, and a thread. The thread should take the text from a text field and write it into text area. I have 4 buttons as follows:

  1. "Start" to start the thread.
  2. "Stop" which stops the thread.
  3. "Pause" which pause and continues the thread.
  4. and "Exit" which stops the thread and exits the program.

I've created the thread and implemented "run()" function in frame's constructor, here it is:

WritingThread = new Thread(new Runnable() {
    @Override
    public void run() {
        String s = WrittenText.getText();
        while(true)
        {
            for(int i = 0; i < 4; i++)
            {
                for(int j = 0; j < s.length(); j++)
                {
                    WritingArea.append("" + s.charAt(j));
                    try {
                        Thread.sleep((int)ThreadSpeedSpinner.getValue());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }   
                }
                WritingArea.append("\n");
            }   
            WritingArea.setText("");
        }
    }
});

and these are the buttons:

JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        if(!WritingThread.isAlive())
            WritingThread.start();
    }
});
JButton btnStop = new JButton("Stop");
btnStop.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        if(WritingThread.isAlive())
            WritingThread.stop();
    }
});
btnPause = new JButton("Pause");
btnPause.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        if(!isPaused)
        {
            if(WritingThread.isAlive())
            {
                WritingThread.suspend();
                btnPause.setText("Continue");
                isPaused = true;
            }
        }
        else
        {
            WritingThread.resume();
            btnPause.setText("Pause");
        }
    }
});
JButton btnExit = new JButton("Exit");
btnExit.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        WritingThread.stop();
        System.exit(0);
    }
});

I have two problems showing up:

  1. When I use stop(), suspend(), or resume(), I get a warning says "The method from the type Thread is deprecated".
  2. When I run the program, I start the thread, then stop it, then try to start it I have this exception

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalThreadStateException
        at java.lang.Thread.start(Unknown Source)
        at com.HomeWork.HomeWork5$6.actionPerformed(HomeWork5.java:140)
        at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
        at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
        at java.awt.Component.processMouseEvent(Unknown Source)
        at javax.swing.JComponent.processMouseEvent(Unknown Source)
        at java.awt.Component.processEvent(Unknown Source)
        at java.awt.Container.processEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Window.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$200(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)
    

I don't want direct answers, I want to understand why I'm getting these errors, and if there any resources I should go through. P.S. I searched for an answer a lot and didn't get anything explaining this problem. Thanks

Upvotes: 2

Views: 3877

Answers (1)

Sorter
Sorter

Reputation: 10220

Threads acquire lock on objects. And the most important part of multithreading is to safely interweave the threads, so that all the threads can use the resource (object). If not dealt with correctly, it leads to deadlock.

When you use stop(), you are killing the thread. That thread is gone forever. It may lead the objects, that stopped thread had acquired, in a inconsistent state.

suspend() is deprecated, because once the thread is suspended other threads won't get the resource, since the suspended thread holds a lock on it.

The image below describes how threads should be correctly used. Use sleep(), wait(), and notify() for interleaving the threads efficiently.

enter image description here

Upvotes: 4

Related Questions