Release Team[oR] 2001 [x] java - 2 - Java Thread Programming by Paul Hyde ISBN: 0672315858 Sams © 1999, 510 pages Learn how to use threads for faster, more efficient Java programming. Table of Contents Back Cover Synopsis by Rebecca Rohan Professional Java developers who've come as far as they can without exploiting threads will find their skills bumped up a few notches by the time they finish Paul Hyde's Java Thread Programming. In a five-and-a-half-page first chapter, the book gives a basic concept briefing, then gets down to business with an example-rich education from the starting thread through inter-thread communication, thread groups, thread pooling, threads and Swing, and more. You'll get an experienced voice on how to gracefully exit from a thread and find out when to use the lead-between-the-eyes SureStop class instead. You'll even find out when multiple threads aren't a good idea. If you're serious about learning what it takes to do Java really, really well, this book is a good place to invest your time. Table of Contents Java Thread Programming - 3 Introduction - 6 Part I Threads Chapter 1 - Introduction to Threads - 10 Chapter 2 - A Simple Two-Thread Example - 14 Chapter 3 - Creating and Starting a Thread - 20 Chapter 4 - Implementing Runnable Versus Extending Thread - 32 Chapter 5 - Gracefully Stopping Threads - 52 Chapter 6 - Thread Prioritization - 79 Chapter 7 - Concurrent Access to Objects and Variables - 94 Chapter 8 - Inter-thread Communication - 131 Chapter 9 - Threads and Swing - 174 Chapter 10 - Thread Groups - 207 Part II Techniques Chapter 11 - Self-Running Objects - 219 Chapter 12 - Exception Callback - 230 Chapter 13 - hread Pooling - 237 Chapter 14 - Waiting for the Full Timeout - 264 - 3 - Chapter 15 - Breaking Out of a Blocked I/O State - 276 Chapter 16 - The SureStop Utility - 299 Chapter 17 - The BooleanLock Utility - 314 Chapter 18 - First-In-First-Out (FIFO) Queue - 331 Part III Appendixes Appendix A - The Thread API - 362 Appendix B - The ThreadGroup API - 370 Back Cover Learn professional thread management techniques from Paul Hyde, a professional Java developer, Sun Certified Programmer for the Java 2 Platform, and advanced Java language instructor. Apply the concepts, code, and real-world solutions in this book to make your Java applications faster, more stable, and more robust. Written by a professional software developer for software developers, Java Thread Programming provides a code-intensive, solution-oriented approach to mastering threads. LEARN THE CONCEPTS AND BUILD THE APPLICATIONS • Start by learning the basics of multithreaded programming in Java and work up to the more advanced concepts. • Suitable tutorial for Java developers that have never worked with threads before, and an excellent reference and source of proven, advanced techniques for Java developers who have had experience working with threads. • Explains how volatile and synchronized should be used to control concurrent access to objects and variables and how to avoid deadlocks. • Discusses how to implement safe and efficient inter-thread communications using the wait/notify mechanism. • Explains how thread prioritization and scheduling affect the execution of threads within an application. • Discusses pros and cons to different approaches and teaches you how to choose the best solutions. • Covers the proper use of threads and Swing, and shows how to use threads to create animation. • Shows you how to use the Collections API in a thread-safe manner. • Comprehensively covers multithread code based on the Java 2 SDK version 1.2.1 and discusses the differences form JDK 1.1 and JDK 1.0. About the Authors Paul Hyde is a professional Java developer and Sun Certified Programmer for the Java 2 Platform. He began developing Java applications at AT&T in 1996 and now has over three years of on-the-job Java development experience. Paul is currently a senior Java consultant for Programix Incorporated, the consulting company he founded in early 1997. He also develops and teaches introductory to advanced Java courses for IT professionals and developers. Java Thread Programming - 4 - Paul Hyde Copyright © 1999 by Sams Publishing Executive Editor Tim Ryan Acquisitions Editor Steve Anglin Development Editors Tiffany Taylor Jon Steever Managing Editor Jodi Jensen Senior Editor Susan Ross Moore Copy Editors Margaret Berson Kate Talbot Indexer Rebecca Hornyak Proofreaders Mona Brown Jill Mazurczyk Technical Editors A lexandre Calsavara Mike Forsythe Team Coordinator Karen Opal Software Development Specialist Michael Hunter Interior Design A nne Jones Cover Design A nne Jones Copy Writer Eric Borgert Layout Technicians Stacey DeRome - 5 - A yanna Lace y Heather Miller All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission from the publisher. No patent liability is assumed with respect to the use of the information contained herein. Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions. Neither is any liability assumed for damages resulting from the use of the information contained herein. International Standard Book Number: 0-672-31585-8 01 00 99 4 3 2 1 Trademarks All terms mentioned in this book that are known to be trademarks or service marks have been appropriately capitalized. Sams Publishing cannot attest to the accuracy of this information. Use of a term in this book should not be regarded as affecting the validity of any trademark or service mark. Sun, Sun Microsystems, SunWorld, Java, and HotJava are trademarks or registered trademarks of Sun Microsystems, Inc. About the Author Paul Hyde graduated from Lehigh University with a Bachelor of Science degree in Electrical Engineering, and began his career at AT&T developing software. There he gained knowledge and experience working with many languages and tools, including C, PowerBuilder, Informix RDBMS, Sybase RDBMS, HTML/CGI, and Java. During this time he acquired a Master of Science degree in Computer Science from Stevens Institute of Technology. Shortly thereafter, while still employed at AT&T, he began teaching night classes in Sybase at the Chubb Institute in New Jersey. In April 1996, Paul started working with Java and realized the great potential it had. Later that year he left AT&T, moved to Minnesota, and founded Programix Incorporated. Programix is a software consulting company specializing in providing Java solutions. Paul is a Sun Certified Java Programmer for the 1.0, 1.1, and 1.2 releases. In his spare time, Paul develops and teaches introductory and advanced Java courses in the Minneapolis area. He enjoys skiing and relaxing on the beach, and stays in shape for these activities by working out, mostly running. In fact, he even completed the 1998 Grandma’s Marathon in Duluth, Minnesota. You can reach Paul at phyde@programix- inc.com. Dedication To my parents, Carol Hyde and the late Richard Hyde, for their incredible support and encouragement throughout my life. Acknowledgments I would like to thank the many people who have helped to bring this book to fruition. All the people at Macmillan Publishing have been a great help. In particular, I’d like to thank Steve Anglin, the Acquisitions Editor at Macmillan, for taking my idea and forming it into a practical project. He championed the concept within Macmillan and got the whole process started. This is my first book, and Steve has been a great guide for me - 6 - throughout the process. His continual attention and encouragement helped keep me going. Tiffany Taylor, the Development Editor at Macmillan, helped me to find my voice and style. She also made sure that what I thought made sense actually made sense! Her guidance has been invaluable throughout the writing of this book. Thanks to Tim Ryan, the Executive Editor for approving and overseeing the whole project. Thanks to Jon Steever, Development Editor, for providing early feedback and good advice at several key times during the production. Thanks to Susan Moore, the Project Editor, for overseeing the editing and author review phase. Thanks to Kate Talbot and Margaret Berson, Copy Editors, for their attention to detail. Thanks to Alexandre Calsavara, the Technical Editor, for all the great suggestions on how to improve the book. I would also like to thank my colleague, Jeff Whiteside, for taking his personal time to read the early chapters in their raw form. Jeff provided excellent advice and suggestions for improving the book. Last, but certainly not least, I would like to thank my fiancé Deb Kostreba for her incredible support throughout this challenging project. Because she helped to streamline my life, I was able to concentrate on writing. At those times when I began to feel overwhelmed, Deb was there to provide encouragement. Paul Hyde Minneapolis, Minnesota June 1999 Tell Us What You Think! As the reader of this book, you are our most important critic and commentator. We value your opinion and want to know what we’re doing right, what we could do better, what areas you’d like to see us publish in, and any other words of wisdom you’re willing to pass our way. As an executive editor for Sams Publishing, I welcome your comments. You can fax, email, or write me directly to let me know what you did or didn’t like about this book—as well as what we can do to make our books stronger. When you write, please be sure to include this book’s title and author as well as your name and phone or fax number. I will carefully review your comments and share them with the author and editors who worked on the book. Fax: 317-581-4770 Email: java@mcp.com Mail: Tim Ryan Executive Editor Sams Publishing 201 West 103rd Street Indianapolis, IN 46290 USA Introduction Structure of This Book This book is for those of you who have started working with Java and have realized that you want to develop multithreaded applications and applets. I don’t assume that you - 7 - know anything about thread programming, so the book starts off with simple, straightforward examples. From there, the chapters become more advanced and comprehensively cover all aspects of thread programming in Java. The second part of the book is dedicated to demonstrating various advanced techniques that can be used in the real world. Chapters 1 through 10 can be read in order because each chapter builds upon the concepts in the preceding one. You can hop around the techniques in Chapters 11 through 18, reading them in just about any order. Some of the techniques are so valuable that they are used in demonstrating other techniques, so you can read up on each technique as you come across it. I developed the example code used in this book using the Java 2 SDK, Standard Edition, version 1.2 (also known as JDK 1.2) from Sun Microsystems. I used this development kit on an Intel Pentium 166MHz machine running Microsoft Windows 95. In this book, some of the statements in the code listings appear in bold-face type simply for emphasis. These source code files are available for download from www.samspublishing.com . When you reach that page, click the Product Support link. On the next page, enter this book’s ISBN number (0672315858) to access the page containing the code. The following is an overview of what is covered in each of the chapters. Chapter 1—”Introduction to Threads” Chapter 1 is an introduction to multithreaded programming and how threads are used in Java. I show you why threads are needed and how they can improve an application’s performance. Chapter 2—”A Simple Two-Thread Example” In Chapter 2, you get to see the most basic example of a multithreaded application. In the application, two threads are running at the same time and print their own messages. I show you the fundamental steps necessary to spawn a new thread. Chapter 3—”Creating and Starting a Thread” Chapter 3 begins to explore the API for the class Thread. You’ll see how to get a handle on the currently executing thread, how threads are named, how to check to see if a thread is still alive, and how to put a thread to sleep for while. Chapter 4—”Implementing Runnable Versus Extending Thread” In Chapter 4, I show you that there is a second way to get a thread to run within an object by using the interface Runnable. This is an especially important feature that works around the lack of multiple inheritance in Java. Chapter 5—”Gracefully Stopping Threads” Chapter 5 shows you how to get threads to stop running. I show you graceful and safe alternatives to the methods that have been deprecated as of JDK 1.2. Chapter 6—”Thread Prioritization” In Chapter 6, I show you how to assign relative priorities to the threads running in the Java Virtual Machine and the effects that priorities have on thread scheduling. Chapter 7—”Concurrent Access to Objects and Variables” - 8 - When more than one thread is running, care must be taken to ensure that the threads interact safely with one another. Chapter 7 shows you how to take steps to prevent race conditions that can corrupt data. I show you the proper use of synchronized and volatile. I also show you how to use the classes in the Collections API in a thread- safe manner. Chapter 8—”Inter-thread Communication” When you have multiple threads safely interacting with shared data, you need a way for one thread to signal another that data has been changed. Chapter 8 shows you how to use wait(), notify(), and notifyAll() to send signals among the threads in an application. Also, I discuss the use of join(), pipes, and ThreadLocal variables. Chapter 9—”Threads and Swing” Chapter 9 shows you how to use multiple threads in an application with a graphical user interface. The Swing toolkit is not inherently multithread-safe, and in this chapter, I show you the steps that must be taken to safely work with it. Chapter 10—”Thread Groups” Chapter 10 explores the ThreadGroup API and ways that you can assign threads to groups. Chapter 11—”Self-Running Objects” Chapter 11 kicks off the technique section by showing you how to create classes that automatically start an internal thread running during construction. This frees a user of a class from having to know that an object has a thread running within it. Chapter 12—”Exception Callback” In Chapter 12, I show you how to find out that another thread has thrown an exception. Chapter 13—”Thread Pooling” Chapter 13 shows how threads can be pooled for shared use in executing short-running blocks of code. I show you how to write a simple Web page server that uses thread pooling to service client requests for pages. Chapter 14—”Waiting For the Full Timeout” As you’ll discover reading Chapter 8, it is not always easy to determine if a thread was notified by another thread or simply timed out waiting to be notified. Chapter 14 shows a technique that can be used to be sure that a thread waits for the full timeout value. Chapter 15—”Breaking Out of a Blocked I/O State” Most of the I/O operations in Java block until the data is written or read. Unfortunately, blocked I/O methods do not respond to interrupts. Chapter 15 shows you some techniques for dealing with this issue. Chapter 16—”The SureStop Utility” - 9 - In Chapter 16, I show you a class that can help ensure that a thread eventually dies. Chapter 17—”The BooleanLock Utility” Chapter 17 shows you a technique for encapsulating the wait/notify mechanism into a compact, multithread-safe class that can be reused in many places in a multithreaded application. Chapter 18—”First-In-First-Out (FIFO) Queue” In Chapter 18, I show you how to build a FIFO queue that is safe to use in a multithreaded environment. In particular, I show you how to create a FIFO queue for holding object references and how to create one for holding bytes. Appendixes: “The Thread API” and “The ThreadGroup API” At the end of the book, there is an appendix explaining the API for the Thread class and another appendix for the ThreadGroup class. Conventions Used in This Book This book uses different typefaces to differentiate between code and regular English, and also to help you identify important concepts. Text that you type and text that should appear on your screen is presented in monospace type. It will look like this to mimic the way text looks on your screen. Placeholders for variables and expressions appear in monospace italic font. You should replace the placeholder with the specific value it represents. Note A Note presents interesting pieces of information related to the surrounding discussion. Tip A Tip offers advice or teaches an easier way to do something. Caution A Warning advises you about potential problems and helps you steer clear of disaster. Part I: Threads Chapter List Chapter 1: Introduction to Threads Chapter 2: A Simple Two-Thread Example Chapter 3: Creating and Starting a Thread - 10 - Chapter 4: Implementing Runnable Versus Extending Thread Chapter 5: Gracefully Stopping Threads Chapter 6: Thread Prioritization Chapter 7: Concurrent Access to Objects and Variables Chapter 8 Inter-thread Communication Chapter 9: Threads and Swing Chapter 10: Thread Groups Chapter 1: Introduction to Threads Overview Isn’t it nice to be able to read and scroll the text of a Web page while the graphics continue to load? How about having a document in a word processor print in the background while you open another document for editing? Perhaps you’ve enjoyed writing a response to an email message while another incoming message with a large file attached is quietly downloaded simultaneously? Threads make all this convenient functionality possible by allowing a multithreaded program to do more than one task at a time. This book helps you learn the skills and techniques necessary to incorporate that kind of useful functionality into your Java programs. What Is a Thread? When a modern operating system wants to start running a program, it creates a new process. A process is a program that is currently executing. Every process has at least one thread running within it. Sometimes threads are referred to as lightweight processes. A thread is a path of code execution through a program, and each thread has its own local variables, program counter (pointer to the current instruction being executed), and lifetime. Most modern operating systems allow more than one thread to be running concurrently within a process. When the Java Virtual Machine (JavaVM, or just VM) is started by the operating system, a new process is created. Within that process, many threads can be spawned (created). Normally, you would think of Java code execution starting with the main() method and proceeding in a path through the program until all the statements in main() are completed. This is an example of a single thread. This “main” thread is spawned by the JavaVM, which begins execution with the main() method, executes all the statements in main(), and dies when the main() method completes. A second thread is always running in the JavaVM: the garbage collection thread. It cleans up discarded objects and reclaims their memory. Therefore, even a simple Java program that only prints Hello World to System.out is running in a multithreaded environment: The two threads are the main thread and the garbage collection thread. [...]... Run of TwoThread.java Main thread New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread Summary This chapter explores how to create a new thread by performing these tasks: - 19 - • Subclassing Thread • Overriding the run() method of Thread. .. TwoThread Remember that the exact order of the messages printed, as well as how long each thread will run between context switches, depends on the thread scheduler Therefore, your output might differ somewhat Listing 3.2 Possible Output from TwoThread Using currentThread() Creator thread New thread Creator thread New thread Creator thread New thread Creator thread New thread Creator thread New thread. .. Creator thread New thread Creator thread New thread Creator thread New thread Creator thread New thread Creator thread New thread Naming a Thread: getName() and setName() Every Thread has a name associated with it If a name is not explicitly supplied, a default one is generated during construction By name, you can differentiate between the various threads running in the JavaVM Using getName() In the Thread. .. the threads happen to be scheduled to run Listing 3.4 Possible Output from TwoThreadGetName name=main name =Thread- 0 name=main - 23 - name =Thread- 0 name=main name =Thread- 0 name=main name =Thread- 0 name=main name =Thread- 0 name =Thread- 0 name =Thread- 0 name=main name =Thread- 0 name =Thread- 0 name=main name =Thread- 0 name=main name=main name=main In addition to a thread named main, the JavaVM starts up other threads... class TwoThread extends Thread { 2: private Thread creatorThread; 3: 4: public TwoThread() { 5: // make a note of the thread that constructed me! 6: creatorThread = Thread. currentThread(); 7: } 8: 9: public void run() { 10: for ( int i = 0; i < 10; i++ ) { 11: printMsg(); 12: } 13: } 14: 15: public void printMsg() { 16: // get a reference to the thread running this 17: Thread t = Thread. currentThread();... nondeterministic thread scheduling Listing 3.6 Possible Output from TwoThreadSetName name=main name=my worker name=main name=my worker name=my worker name=main name=my worker name=main name=my worker name=main name=my worker name=main name=my worker name=main name=my worker name=my worker name=main name=my worker name=main name=main thread thread thread thread thread thread thread thread thread thread Thread. .. In Java, a ThreadGroup (much like a directory) can contain Threads and other ThreadGroups These other ThreadGroups can, in turn, contain other Threads and ThreadGroups Every Thread (much like a file) is a member of a ThreadGroup, which may itself be a member of another ThreadGroup If a ThreadGroup is not specified at the time of a Thread s construction, the ThreadGroup is inherited from the Thread that... loop completes, the thread returns from the run() method and quietly dies Spawning a New Thread New threads are spawned from threads that are already running First, a new Thread instance must be constructed In this example, a new TwoThread object will work just fine because TwoThread IS-A Thread: TwoThread tt = new TwoThread(); The next step is to kick off the execution of the thread by invoking the... the worker thread is no longer alive Listing 3.8 Possible Output from TwoThreadAlive before start(), tt.isAlive()=false name=my worker thread name=my worker thread name=my worker thread just after start(), tt.isAlive()=true name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread name=my worker thread name=main... Listing 3.10 Sample Output from TwoThreadSleep just entered loop() name=my worker thread name=my worker thread just entered loop() name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread name=main name=my worker thread about to leave loop() name=main . New thread Main thread New thread Main thread New thread Main thread New thread Main thread New thread. Run of TwoThread.java Main thread New thread Main thread New thread Main thread New thread Main thread