[ Pobierz całość w formacie PDF ]
.swing.*;import java.awt.*;import java.awt.event.*;import com.bruceeckel.swing.*;class Blocked extends Thread {public synchronized void run() {try {wait(); // Blocks} catch(InterruptedException e) {System.err.println("Interrupted");}System.out.println("Exiting run()");}}public class Interrupt extends JApplet {private JButtoninterrupt = new JButton("Interrupt");private Blocked blocked = new Blocked();public void init() {Container cp = getContentPane();cp.setLayout(new FlowLayout());cp.add(interrupt);interrupt.addActionListener(new ActionListener() {publicvoid actionPerformed(ActionEvent e) {System.out.println("Button pressed");if(blocked == null) return;Thread remove = blocked;blocked = null; // to release itremove.interrupt();}});blocked.start();}public static void main(String[] args) {Console.run(new Interrupt(), 200, 100);}} ///:~The wait( ) insideBlocked.run( ) produces the blocked thread.When you press thebutton, the blocked reference is set to null so the garbagecollector will clean it up, and then the object’s interrupt( )method is called.The first time you press the button you’ll see that thethread quits, but after that there’s no thread to kill so you just seethat the button has been pressed.[ Add Comment ]Thesuspend( ) and resume( ) methods turn out to beinherently deadlock-prone.When you call suspend( ), the targetthread stops but it still holds any locks that it has acquired up to that point.So no other thread can access the locked resources until the thread is resumed.Any thread that wants to resume the target thread and also tries to use any ofthe locked resources produces deadlock.You should not usesuspend( ) and resume( ), but instead put a flag in yourThread class to indicate whether the thread should be active orsuspended.If the flag indicates that the thread issuspended,the thread goes into a wait using wait( ).When the flag indicatesthat the thread should be resumed the thread is restarted withnotify( ).An example can be produced by modifyingCounter2.java.Although the effect is similar, you’ll notice thatthe code organization is quitedifferent—anonymousinner classes are used for all of the listeners and the Thread is aninner class, which makes programming slightly more convenient since iteliminates some of the extra bookkeeping necessary in Counter2.java:[ Add Comment ]//: c14:Suspend.java// The alternative approach to using suspend()// and resume(), which are deprecated in Java 2.// <applet code=Suspend width=300 height=100>// </applet>import javax.swing.*;import java.awt.*;import java.awt.event.*;import com.bruceeckel.swing.*;public class Suspend extends JApplet {private JTextField t = new JTextField(10);private JButtonsuspend = new JButton("Suspend"),resume = new JButton("Resume");private Suspendable ss = new Suspendable();class Suspendable extends Thread {private int count = 0;private boolean suspended = false;public Suspendable() { start(); }public void fauxSuspend() {suspended = true;}public synchronized void fauxResume() {suspended = false;notify();}public void run() {while (true) {try {sleep(100);synchronized(this) {while(suspended)wait();}} catch(InterruptedException e) {System.err.println("Interrupted");}t.setText(Integer.toString(count++));}}}public void init() {Container cp = getContentPane();cp.setLayout(new FlowLayout());cp.add(t);suspend.addActionListener(new ActionListener() {publicvoid actionPerformed(ActionEvent e) {ss.fauxSuspend();}});cp.add(suspend);resume.addActionListener(new ActionListener() {publicvoid actionPerformed(ActionEvent e) {ss.fauxResume();}});cp.add(resume);}public static void main(String[] args) {Console
[ Pobierz całość w formacie PDF ]