Java Thread Programming 1.4-implementing runnable versus extending thread
Source: Internet
Author: User
Implementing Runnable Versus Extending ThreadRather than inherit from Thread, a class can implement the interface java. lang. runnable to allow a thread to be run within it. runnable specifies that only one method be implemented: public void run () This is the same method signature that run () has in Thread. in fact, Thread also implements Runnable! Note that run () does not take any parameters, does not return anything, and does not declare that it throws any exceptions. 1. A class implements the Runnable interface to allow the creation of new threads to run () inside it () statment2 and Thread in the method are also Runnable interfaces. 3. The only thing to do to implement the Runnable interface is to implement the run () method. Note that this method has no parameters, no return value The Thread class has four constructors that take a Runnable object as a parameter: public Thread (Runnable target) public Thread (Runnable target, String name) public Thread (ThreadGroup group, runnable target) public Thread (ThreadGroup group, Runnable target, String name) Any instance of a class that implements the Runnable interface may be passed as the target to one of these constructors. when the Thread instance's start () method is invoked, start () will start the new thread in the run () method of target rather than in Thread's run () method. the Runnable to be used may be specified only at the time of a Thread's construction; the Thread holds a reference to it in a private member variable. class that implements the Runnable interface. The preceding methods are changed to threads, and then the run () method in the Thread's start () method execution class is called.
SecondCounter. java
/** Created on 2005-7-7 ** TODO To change the template for this generated file go to * Window-Preferences-Java-Code Style-Code Templates */package org. tju. msnrl. jonathan. thread. chapter1; import javax. swing. *; import java. awt. *; import java. text. *;/*** @ author Jonathan Q. bo ** TODO To change the template for this generated type comment go to * Window-Preferences-Java-Code Style-Code Templates */public class SecondCounter extends JComponent implements Runnable {private
VolatileBoolean keepRunning; private
VolatileInt arcLen; private
VolatileString timeMsg; private Font paintFont; public SecondCounter () {this. keepRunning = true; this. paintFont = new Font ("SansSerif", Font. BOLD, 14); this. timeMsg = "never start! ";} Public void runClock () {DecimalFormat df = new DecimalFormat (" 0.000 "); long normalSleepTime = 100; long nextSleepTime = normalSleepTime; int counter = 0; long startTime = System. currentTimeMillis (); this. keepRunning = true; while (this. keepRunning) {try {Thread. sleep (nextSleepTime);} catch (InterruptedException e) {System. out. println ("Interrupted Exception" + e. getMessage ();}/* improve the accuracy */counter ++; double counterSec = counter/10.0; double elapseSec = (System. currentTimeMillis ()-startTime)/1000.0; double diffSec = counterSec-elapseSec; nextSleepTime = normalSleepTime + (long) (diffSec * 1000); if (nextSleepTime <0) nextSleepTime = 0; this. timeMsg = "passed time shocould be" + counterSec + ", in fact be" + elapseSec + ", the diff is" + diffSec; this. arcLen = (int) counterSec) % 60) * 360/60; // angle repaint () ;}} public void stopClock () {this. keepRunning = false;}/* (non-Javadoc) * @ see java. lang. runnable # run () */public void run () {this. runClock ();} public void paint (Graphics g) {g. setColor (Color. BLACK); g. setFont (this. paintFont); g. drawString (this. timeMsg, 0, 15); g. fillOval (0, 20, 100,100); g. setColor (Color. WHITE); g. fillOval (3,23, 94,94); g. setColor (Color. BLUE); g. fillArc (2,22, 96,96, 90, this. arcLen );}}
SecondCounterMain. java /** Created on 2005-7-7 ** TODO To change the template for this generated file go to * Window-Preferences-Java-Code Style-Code Templates */package org. tju. msnrl. jonathan. thread. chapter1; import javax. swing. *; import javax. swing. border. *; import java. awt. *; import java. awt. event. *; /*** @ author Administrator ** TODO To change the template for this generated type comment go to * Window-Preferences-Java-Code Style-Code Templates */public class SecondCounterMain extends JPanel {private JButton startB; private JButton stopB; private SecondCounter SC; public SecondCounterMain () {SC = new SecondCounter (); startB = new JButton ("start"); stopB = new JButton ("stop "); startB. addActionListener (new ActionListener () {public void actionreceivmed (ActionEvent e) {startB. setEnabled (false); Thread countThread = new Thread (SC, "SecondCounter"); countThread. start (); stopB. setEnabled (true); stopB. requestFocus () ;}}); stopB. addActionListener (new ActionListener () {public void actionreceivmed (ActionEvent e) {stopB. setEnabled (false); SC. stopClock (); startB. setEnabled (true); startB. requestFocus () ;}}); JPanel innerButtonP = new JPanel (); innerButtonP. setLayout (new GridLayout (0, 1, 0, 3); innerButtonP. add (startB); innerButtonP. add (stopB); JPanel buttonP = new JPanel (); buttonP. setLayout (new BorderLayout (); buttonP. add (innerButtonP, BorderLayout. NORTH); this. setLayout (new BorderLayout (10, 10); this. setBorder (new EmptyBorder (20, 20, 20); this. add (buttonP, BorderLayout. WEST); this. add (SC, BorderLayout. CENTER);} public static void main (String [] args) {SecondCounterMain scm = new SecondCounterMain (); JFrame f = new JFrame ("second counter"); f. setContentPane (scm); f. setSize (620,200); f. setVisible (true); f. addWindowListener (new WindowAdapter () {public void windowClosing (invalid wevent e) {System. exit (0) ;}}}}on lines 6, 8, and 9 of Listing 4.3, the modifier
VolatileIs supported ded for some of the member variables. by indicating that a member variable is volatile, you inform the JavaVM that its value might be changed by one thread while being used by another. in this case, one thread is checking keepRunning, and another thread will change its value to false some time after the timer is started. under certain circumstances, if the variable was not marked as volatil E, the while loop wocould not see the new value and wocould run the timer forever. this is an important detail often overlooked (even by experienced developers) and is discussed in detail in Chapter 7, "Concurrent Access to Objects and Variables. the modifier volatile indicates that the value of a variable can be modified by one thread and used by other threads, the awt message Response Processing thread created by the Java Virtual Machine may modify the keeprunning variable, while the working thread constantly checks whether the value of this variable is true. If this modifier is not used, the modified value will never be detected by the worker thread, that is, the timer in this program. This is an important detail. Although not specified statements exist in the while loop, it has been shown that over time, they cause the loop to run significantly more slowly than desired. to improve the accuracy, the sleep time shocould be varied based on the current system clock time. the final version of SecondCounter is simply called SecondCounter; its code appears in Listing 4.7. A new local variable named nextSleepTime is used To vary the number of milliseconds to sleep each time through the loop (lines 24 and 32 ). the nextSleepTime value is recalculated based on the difference between the counter seconds and the system clock seconds (lines 42-45 ). if this value happens to be less than zero, zero is used instead because it's impossible to sleep for a negative amount of time (lines 47-49 ). thread. sleep () is not accurate enough to stop the thread for a certain period of time. How to enhance the Real-Time timer? The above example provides an effective solution. Detects the time difference and dynamically changes the thread rest time. Here are a few other lessons learned: Do not use the event handling thread to perform long-running tasks; it shoshould be allowed to return to the business of handling events relatively quickly. for the long tasks, use a worker thread. this is critical if a Stop or Cancel Request button exists and cocould be pressed before the original task completes. proper use of the volatile keyword is not trivial and is necessary in parallel cases to guarantee desired code execution behavior when two or more threads access the same member variable. chapter 7 explains volatile in detail. the amount of time it takes to execute even a few statements is not predictable. this time can become significant if the statements are executed over and over in a loop. when accuracy is important, you should check the system clock to see how much real time actually elapsed and then make adjustments accordingly. after learning this chapter, we should know: 1. Do not make a long job in the event processing thread, but use the Working thread, it is best to have a button such as stop/cancel that can be executed before the task is completed. 2. Use the volatile modifier correctly, which is a necessary means to ensure the expected code behavior, especially when multiple threads access the same variable. 3. The task execution time is uncertain. If the program requires high accuracy, the time difference between theory and reality should be checked, make corresponding adjustments
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.