Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Java Multithreading: Differences, Animation, and Synchronization, Lecture notes of Compilers

The concept of multithreading and threads in Java, their differences, and provides an example of animating bouncing balls using separate threads. It covers creating and starting threads, thread states, priorities, daemon threads, and thread groups. Additionally, it discusses the importance of synchronization to prevent data inconsistencies in multithreaded environments.

What you will learn

  • How can you ensure data consistency in a multithreaded environment?
  • What is the difference between multiple processes and multiple threads?
  • What is the role of thread priorities in Java?
  • What is multithreading in Java?
  • How do you create and start a thread in Java?

Typology: Lecture notes

2021/2022

Uploaded on 09/12/2022

sumaira
sumaira 🇺🇸

4.8

(57)

263 documents

1 / 84

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
1
Multithreading
WHAT ARE THREADS?
INTERRUP TING THREAD S
THREAD STATES
THREAD PROPERTIE S
SYNCHRONIZATION
BLOCKING QUEUES
THREAD-SAFE COLLECTIONS
CALLABLES AND FUTURES
EXECUTORS
SYNCHRONIZERS
THREADS AND SWING
You are probably familiar with multitasking in your operating system: the ability to
have more than one program working at what seems like the same time. For example, you
can print while editing or sending a fax. Of course, unless you have a multiple-processor
machine, the operating system is really doling out CPU time to each program, giving the
impression of parallel activity. This resource distribution is possible because although you
may think you are keeping the computer busy by, for example, entering data, much of the
CPU’s time will be idle.
Multitasking can be done in two ways, depending on whether the operating system inter-
rupts programs without consulting with them first or whether programs are only interrupted
when they are willing to yield control. The former is called preemptive multitasking; the lat-
ter is called cooperative (or, simply, nonpreemptive) multitasking. Older operating systems
such as Windows 3.x and Mac OS 9 are cooperative multitasking systems, as are the operat-
ing systems on simple devices such as cell phones. UNIX/Linux, Windows NT/XP (and
Windows 9x for 32-bit programs), and OS X are preemptive. Although harder to imple-
ment, preemptive multitasking is much more effective. With cooperative multitasking, a
badly behaved program can hog everything.
Multithreaded programs extend the idea of multitasking by taking it one level lower: indi-
vidual programs will appear to do multiple tasks at the same time. Each task is usually
called a thread—which is short for thread of control. Programs that can run more than one
thread at once are said to be multithreaded.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51
pf52
pf53
pf54

Partial preview of the text

Download Java Multithreading: Differences, Animation, and Synchronization and more Lecture notes Compilers in PDF only on Docsity!

Multithreading

 WHAT ARE T HREADS?

 INTERRUPTING T HREADS

 THREAD STATES

 THREAD PROPERTIES

 SYNCHRONIZATION

 BLOCKING QUEUES

 THREAD-SAFE COLLECTIONS

 CALLABLES AND F UTURES

 E XECUTORS

 SYNCHRONIZERS

 THREADS AND S WING

You are probably familiar with multitasking in your operating system: the ability to

have more than one program working at what seems like the same time. For example, you

can print while editing or sending a fax. Of course, unless you have a multiple-processor

machine, the operating system is really doling out CPU time to each program, giving the

impression of parallel activity. This resource distribution is possible because although you

may think you are keeping the computer busy by, for example, entering data, much of the

CPU’s time will be idle.

Multitasking can be done in two ways, depending on whether the operating system inter-

rupts programs without consulting with them first or whether programs are only interrupted

when they are willing to yield control. The former is called preemptive multitasking ; the lat-

ter is called cooperative (or, simply, nonpreemptive) multitasking. Older operating systems

such as Windows 3.x and Mac OS 9 are cooperative multitasking systems, as are the operat-

ing systems on simple devices such as cell phones. UNIX/Linux, Windows NT/XP (and

Windows 9x for 32-bit programs), and OS X are preemptive. Although harder to imple-

ment, preemptive multitasking is much more effective. With cooperative multitasking, a

badly behaved program can hog everything.

Multithreaded programs extend the idea of multitasking by taking it one level lower: indi-

vidual programs will appear to do multiple tasks at the same time. Each task is usually

called a thread —which is short for thread of control. Programs that can run more than one

thread at once are said to be multithreaded.

Core Java

So, what is the difference between multiple processes and multiple threads? The essential dif-

ference is that while each process has a complete set of its own variables, threads share the

same data. This sounds somewhat risky, and indeed it can be, as you will see later in this

chapter. However, shared variables make communication between threads more efficient

and easier to program than interprocess communication. Moreover, on some operating sys-

tems, threads are more “lightweight” than processes—it takes less overhead to create and

destroy individual threads than it does to launch new processes.

Multithreading is extremely useful in practice. For example, a browser should be able to

simultaneously download multiple images. A web server needs to be able to serve concur-

rent requests. The Java programming language itself uses a thread to do garbage collection

in the background—thus saving you the trouble of managing memory! Graphical user

interface (GUI) programs have a separate thread for gathering user interface events from

the host operating environment. This chapter shows you how to add multithreading capa-

bility to your Java applications.

Multithreading changed dramatically in JDK 5.0, with the addition of a large number of

classes and interfaces that provide high-quality implementations of the mechanisms that

most application programmers will need. In this chapter, we explain the new features of

JDK 5.0 as well as the classic synchronization mechanisms, and help you choose between

them.

Fair warning: multithreading can get very complex. In this chapter, we cover all the

tools that an application programmer is likely to need. However, for more intricate sys-

tem-level programming, we suggest that you turn to a more advanced reference, such

as Concurrent Programming in Java by Doug Lea [Addison-Wesley 1999].

What Are Threads?

Let us start by looking at a program that does not use multiple threads and that, as a

consequence, makes it difficult for the user to perform several tasks with that pro-

gram. After we dissect it, we then show you how easy it is to have this program run

separate threads. This program animates a bouncing ball by continually moving the

ball, finding out if it bounces against a wall, and then redrawing it. (See Figure 1–1.)

As soon as you click the Start button, the program launches a ball from the upper-left cor-

ner of the screen and the ball begins bouncing. The handler of the Start button calls the

addBall method. That method contains a loop running through 1,000 moves. Each call to move

moves the ball by a small amount, adjusts the direction if it bounces against a wall, and

then redraws the panel.

Ball ball = new Ball(); panel.add(ball);

for (int i = 1; i <= STEPS; i++) { ball.move(panel.getBounds()); panel.paint(panel.getGraphics()); Thread.sleep(DELAY); }

The static sleep method of the Thread class pauses for the given number of milliseconds.

Core Java

  1. import javax.swing.*;
  2. /**
  3. Shows an animated bouncing ball.
  4. */
  5. public class Bounce
  6. {
  7. public static void main(String[] args)
  8. {
  9. JFrame frame = new BounceFrame();
  10. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  11. frame.setVisible(true);
  12. }
  13. }
  14. /**
  15. A ball that moves and bounces off the edges of a
  16. rectangle
  17. */
  18. class Ball
  19. {
  20. /**
  21. Moves the ball to the next position, reversing direction
  22. if it hits one of the edges
  23. */
  24. public void move(Rectangle2D bounds)
  25. {
  26. x += dx;
  27. y += dy;
  28. if (x < bounds.getMinX())
  29. {
  30. x = bounds.getMinX();
  31. dx = -dx;
  32. }
  33. if (x + XSIZE >= bounds.getMaxX())
  34. {
  35. x = bounds.getMaxX() - XSIZE;
  36. dx = -dx;
  37. }
  38. if (y < bounds.getMinY())
  39. {
  40. y = bounds.getMinY();
  41. dy = -dy;
  42. }
  43. if (y + YSIZE >= bounds.getMaxY())
  44. {
  45. y = bounds.getMaxY() - YSIZE;
  46. dy = -dy;
  47. }
  48. }
  49. /**
  50. Gets the shape of the ball at its current position.
  51. */
  52. public Ellipse2D getShape()

1 • Multithreading

  1. return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
  2. }
  3. private static final int XSIZE = 15;
  4. private static final int YSIZE = 15;
  5. private double x = 0;
  6. private double y = 0;
  7. private double dx = 1;
  8. private double dy = 1;
  9. }
  10. /**
  11. The panel that draws the balls.
  12. */
  13. class BallPanel extends JPanel
  14. {
  15. /**
  16. Add a ball to the panel.
  17. @param b the ball to add
  18. */
  19. public void add(Ball b)
  20. {
  21. balls.add(b);
  22. }
  23. public void paintComponent(Graphics g)
  24. {
  25. super.paintComponent(g);
  26. Graphics2D g2 = (Graphics2D) g;
  27. for (Ball b : balls)
  28. {
  29. g2.fill(b.getShape());
  30. }
  31. }
  32. private ArrayList balls = new ArrayList();
  33. }
  34. /**
  35. The frame with panel and buttons.
  36. */
  37. class BounceFrame extends JFrame
  38. {
  39. /**
  40. Constructs the frame with the panel for showing the
  41. bouncing ball and Start and Close buttons
  42. */
  43. public BounceFrame()
  44. {
  45. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
  46. setTitle("Bounce");
  47. panel = new BallPanel();
  48. add(panel, BorderLayout.CENTER);

1 • Multithreading

  1. private BallPanel panel;

  2. public static final int DEFAULT_WIDTH = 450;

  3. public static final int DEFAULT_HEIGHT = 350;

  4. public static final int STEPS = 1000;

  5. public static final int DELAY = 3;

  6. }

- static void sleep(long millis) 

sleeps for the given number of milliseconds.

Using Threads to Give Other Tasks a Chance

We will make our bouncing-ball program more responsive by running the code that moves

the ball in a separate thread. In fact, you will be able to launch multiple balls. Each of them

is moved by its own thread. In addition, the AWT event dispatch thread continues running in

parallel, taking care of user interface events. Because each thread gets a chance to run, the

main thread has the opportunity to notice when a user clicks the Close button while the

balls are bouncing. The thread can then process the “close” action.

Here is a simple procedure for running a task in a separate thread:

1. Place the code for the task into the run method of a class that implements the Runnable

interface. That interface is very simple, with a single method:

public interface Runnable { void run(); }

You simply implement a class, like this:

class MyRunnable implements Runnable { public void run() { task code } }

2. Construct an object of your class:

Runnable r = new MyRunnable();

3. Construct a Thread object from the Runnable:

Thread t = new Thread(r);

4. Start the thread.

t.start();

To make our bouncing-ball program into a separate thread, we need only implement a

class BallRunnable and place the code for the animation inside the run method, as in the

following code:

class BallRunnable implements Runnable {

...

java.lang.Thread 1.

Parameters: millis^ The number of milliseconds to sleep

Core Java

public void run() { try { for (int i = 1; i <= STEPS; i++) { ball.move(component.getBounds()); component.repaint(); Thread.sleep(DELAY); } } catch (InterruptedException exception) { } }

... }

Again, we need to catch an InterruptedException that the sleep method threatens to throw. We

discuss this exception in the next section. Typically, a thread is terminated by being inter-

rupted. Accordingly, our run method exits when an InterruptedException occurs.

Whenever the Start button is clicked, the addBall method launches a new thread (see

Figure 1–2):

Ball b = new Ball(); panel.add(b); Runnable r = new BallRunnable(b, panel); Thread t = new Thread(r); t.start();

Figure 1–2: Running multiple threads

That’s all there is to it! You now know how to run tasks in parallel. The remainder of this

chapter tells you how to control the interaction between threads.

The complete code is shown in Example 1–2.

Core Java

  1. public void run()

  2. {

  3. try

  4. {

  5. for (int i = 1; i <= STEPS; i++)

  6. {

  7. ball.move(component.getBounds());

  8. component.repaint();

  9. Thread.sleep(DELAY);

  10. }

  11. }

  12. catch (InterruptedException e)

  13. {

  14. }

  15. }

  16. private Ball ball;

  17. private Component component;

  18. public static final int STEPS = 1000;

  19. public static final int DELAY = 5;

  20. }

  21. /**

  22. A ball that moves and bounces off the edges of a

  23. rectangle

  24. */

  25. class Ball

  26. {

  27. /**

  28. Moves the ball to the next position, reversing direction

  29. if it hits one of the edges

  30. */

  31. public void move(Rectangle2D bounds)

  32. {

  33. x += dx;

  34. y += dy;

  35. if (x < bounds.getMinX())

  36. {

  37. x = bounds.getMinX();

  38. dx = -dx;

  39. }

  40. if (x + XSIZE >= bounds.getMaxX())

  41. {

  42. x = bounds.getMaxX() - XSIZE;

  43. dx = -dx;

  44. }

  45. if (y < bounds.getMinY())

  46. {

  47. y = bounds.getMinY();

  48. dy = -dy;

  49. }

  50. if (y + YSIZE >= bounds.getMaxY())

  51. {

  52. y = bounds.getMaxY() - YSIZE;

1 • Multithreading

  1. dy = -dy;
  2. }
  3. }
  4. /**
  5. Gets the shape of the ball at its current position.
  6. */
  7. public Ellipse2D getShape()
  8. {
  9. return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
  10. }
  11. private static final int XSIZE = 15;
  12. private static final int YSIZE = 15;
  13. private double x = 0;
  14. private double y = 0;
  15. private double dx = 1;
  16. private double dy = 1;
  17. }
  18. /**
  19. The panel that draws the balls.
  20. */
  21. class BallPanel extends JPanel
  22. {
  23. /**
  24. Add a ball to the panel.
  25. @param b the ball to add
  26. */
  27. public void add(Ball b)
  28. {
  29. balls.add(b);
  30. }
  31. public void paintComponent(Graphics g)
  32. {
  33. super.paintComponent(g);
  34. Graphics2D g2 = (Graphics2D) g;
  35. for (Ball b : balls)
  36. {
  37. g2.fill(b.getShape());
  38. }
  39. }
  40. private ArrayList balls = new ArrayList();
  41. }
  42. /**
  43. The frame with panel and buttons.
  44. */
  45. class BounceFrame extends JFrame
  46. {
  47. /**
  48. Constructs the frame with the panel for showing the
  49. bouncing ball and Start and Close buttons
  50. */

1 • Multithreading

  1. public static final int DEFAULT_HEIGHT = 350;
  2. public static final int STEPS = 1000;
  3. public static final int DELAY = 3;
  4. }
- Thread(Runnable target) 

constructs a new thread that calls the run() method of the specified target.

  • void start()

starts this thread, causing the run() method to be called. This method will return

immediately. The new thread runs concurrently.

  • void run()

calls the run method of the associated Runnable.

  • void run()

You must override this method and supply the instructions for the task that you

want to have executed.

Interrupting Threads

A thread terminates when its run method returns. In JDK 1.0, there also was a stop method

that another thread could call to terminate a thread. However, that method is now depre-

cated. We discuss the reason on page 46.

There is no longer a way to force a thread to terminate. However, the interrupt method

can be used to request termination of a thread.

When the interrupt method is called on a thread, the interrupted status of the thread is set.

This is a Boolean flag that is present in every thread. Each thread should occasionally check

whether it has been interrupted.

To find out whether the interrupted status was set, first call the static Thread.currentThread

method to get the current thread and then call the isInterrupted method:

while ( !Thread.currentThread().isInterrupted() && more work to do ) { do more work }

However, if a thread is blocked, it cannot check the interrupted status. This is where

the InterruptedException comes in. When the interrupt method is called on a blocked

thread, the blocking call (such as sleep or wait) is terminated by an InterruptedException.

There is no language requirement that a thread that is interrupted should terminate.

Interrupting a thread simply grabs its attention. The interrupted thread can decide

how to react to the interruption. Some threads are so important that they should han-

dle the exception and continue. But quite commonly, a thread will simply want to

interpret an interruption as a request for termination. The run method of such a thread

has the following form:

public void run() { try {

...

java.lang.Thread 1.

java.lang.Runnable 1.

Core Java

while (!Thread.currentThread().isInterrupted() && more work to do ) { do more work } } catch(InterruptedException e) { // thread was interrupted during sleep or wait } finally { cleanup, if required } // exiting the run method terminates the thread }

The isInterrupted check is not necessary if you call the sleep method after every work

iteration. The sleep method throws an InterruptedException if you call it when the inter-

rupted status is set. Therefore, if your loop calls sleep, don’t bother checking the inter-

rupted status and simply catch the InterruptedException. Then your run method has the

form

public void run() { try {

... while ( more work to do ) { do more work Thread.sleep( delay ); } } catch(InterruptedException e) { // thread was interrupted during sleep or wait } finally { cleanup, if required } // exiting the run method terminates the thread }

CAUTION: When the sleep method throws an InterruptedException, it also clears the interrupted status.

NOTE: There are two very similar methods, interrupted and isInterrupted. The interrupted method is a static method that checks whether the current thread has been interrupted. Further- more, calling the interrupted method clears the interrupted status of the thread. On the other hand, the isInterrupted method is an instance method that you can use to check whether any thread has been interrupted. Calling it does not change the interrupted status.

Core Java

  • Blocked
  • Dead

Each of these states is explained in the sections that follow.

New Threads

When you create a thread with the new operator—for example, new Thread(r)—the thread is

not yet running. This means that it is in the new state. When a thread is in the new state, the

program has not started executing code inside of it. A certain amount of bookkeeping

needs to be done before a thread can run.

Runnable Threads

Once you invoke the start method, the thread is runnable. A runnable thread may or

may not actually be running. It is up to the operating system to give the thread time

to run. (The Java specification does not call this a separate state, though. A running

thread is still in the runnable state.)

NOTE: The runnable state has nothing to do with the Runnable interface.

Once a thread is running, it doesn’t necessarily keep running. In fact, it is desirable if

running threads occasionally pause so that other threads have a chance to run. The

details of thread scheduling depend on the services that the operating system provides.

Preemptive scheduling systems give each runnable thread a slice of time to perform its

task. When that slice of time is exhausted, the operating system preempts the thread and

gives another thread an opportunity to work (see Figure 1–4 on page 27). When selecting

the next thread, the operating system takes into account the thread priorities —see page 19

for more information on priorities.

All modern desktop and server operating systems use preemptive scheduling. However,

small devices such as cell phones may use cooperative scheduling. In such a device, a

thread loses control only when it calls a method such as sleep or yield.

On a machine with multiple processors, each processor can run a thread, and you can have

multiple threads run in parallel. Of course, if there are more threads than processors, the

scheduler still has to do time-slicing.

Always keep in mind that a runnable thread may or may not be running at any given time.

(This is why the state is called “runnable” and not “running.”)

Blocked Threads

A thread enters the blocked state when one of the following actions occurs:

  • The thread goes to sleep by calling the sleep method.
  • The thread calls an operation that is blocking on input/output , that is, an operation that

will not return to its caller until input and output operations are complete.

  • The thread tries to acquire a lock that is currently held by another thread. We discuss

locks on page 27.

  • The thread waits for a condition—see page 30.
  • Someone calls the suspend method of the thread. However, this method is deprecated,

and you should not call it in your code.

Figure 1–3 shows the states that a thread can have and the possible transitions from one

state to another. When a thread is blocked (or, of course, when it dies), another thread can

1 • Multithreading

be scheduled to run. When a blocked thread is reactivated (for example, because it has

slept the required number of milliseconds or because the I/O it waited for is complete), the

scheduler checks to see if it has a higher priority than the currently running thread. If so, it

preempts the current thread and picks a new thread to run.

Figure 1–3: Thread states

A thread moves out of the blocked state and back into the runnable state by one of the fol-

lowing pathways.

1. If a thread has been put to sleep, the specified number of milliseconds must expire.

2. If a thread is waiting for the completion of an input or output operation, then the oper-

ation must have finished.

3. If a thread is waiting for a lock that was owned by another thread, then the other

thread must relinquish ownership of the lock. (It is also possible to wait with a timeout.

Then the thread unblocks when the timeout elapses.)

4. If a thread waits for a condition, then another thread must signal that the condition

may have changed. (If the thread waits with a timeout, then the thread is unblocked

when the timeout elapses.)

block on I/O

wait

dead

new

runnable

sleep

done sleeping

suspend

resume

notify

I/O complete

run method exits

start

blocked

stop

wait for lock

lock available

1 • Multithreading

Thread Priorities

In the Java programming language, every thread has a priority. By default, a thread inherits

the priority of its parent thread, that is, the thread that started it. You can increase or

decrease the priority of any thread with the setPriority method. You can set the priority to

any value between MIN_PRIORITY (defined as 1 in the Thread class) and MAX_PRIORITY (defined as

10). NORM_PRIORITY is defined as 5.

Whenever the thread-scheduler has a chance to pick a new thread, it prefers threads with

higher priority. However, thread priorities are highly system dependent. When the virtual

machine relies on the thread implementation of the host platform, the Java thread priorities

are mapped to the priority levels of the host platform, which may have more or fewer

thread priority levels.

For example, Windows NT/XP has seven priority levels. Some of the Java priorities will

map to the same operating system level. In the Sun JVM for Linux, thread priorities are

ignored altogether—all threads have the same priority.

Thus, it is best to treat thread priorities only as hints to the scheduler. You should never

structure your programs so that their correct functioning depends on priority levels.

CAUTION: If you do use priorities, you should be aware of a common beginner’s error. If you have several threads with a high priority that rarely block, the lower-priority threads may never execute. Whenever the scheduler decides to run a new thread, it will choose among the high- est-priority threads first, even though that may starve the lower-priority threads completely.

  • void setPriority(int newPriority)

sets the priority of this thread. The priority must be between Thread.MIN_PRIORITY and

Thread.MAX_PRIORITY. Use Thread.NORM_PRIORITY for normal priority.

  • static int MIN_PRIORITY

is the minimum priority that a Thread can have. The minimum priority value is 1.

  • static int NORM_PRIORITY

is the default priority of a Thread. The default priority is 5.

  • static int MAX_PRIORITY

is the maximum priority that a Thread can have. The maximum priority value is 10.

  • static void yield()

causes the currently executing thread to yield. If there are other runnable threads

with a priority at least as high as the priority of this thread, they will be scheduled

next. Note that this is a static method.

Daemon Threads

You can turn a thread into a daemon thread by calling

t.setDaemon(true);

There is nothing demonic about such a thread. A daemon is simply a thread that has no

other role in life than to serve others. Examples are timer threads that send regular

“timer ticks” to other threads. When only daemon threads remain, the virtual machine

exits. There is no point in keeping the program running if all remaining threads are

daemons.

java.lang.Thread 1.

Core Java

  • void setDaemon(boolean isDaemon)

marks this thread as a daemon thread or a user thread. This method must be called

before the thread is started.

Thread Groups

Some programs contain quite a few threads. It then becomes useful to categorize them by

functionality. For example, consider an Internet browser. If many threads are trying to

acquire images from a server and the user clicks on a Stop button to interrupt the loading

of the current page, then it is handy to have a way of interrupting all these threads simulta-

neously. The Java programming language lets you construct what it calls a thread group so

that you can simultaneously work with a group of threads.

You construct a thread group with the constructor:

String groupName =.. .; ThreadGroup g = new ThreadGroup(groupName)

The string argument of the ThreadGroup constructor identifies the group and must be unique.

You then add threads to the thread group by specifying the thread group in the thread

constructor.

Thread t = new Thread(g, threadName);

To find out whether any threads of a particular group are still runnable, use the activeCount

method.

if (g.activeCount() == 0) { // all threads in the group g have stopped }

To interrupt all threads in a thread group, simply call interrupt on the group object.

g.interrupt(); // interrupt all threads in group g

However, executors let you achieve the same task without requiring the use of thread

groups—see page 63.

Thread groups can have child subgroups. By default, a newly created thread group becomes

a child of the current thread group. But you can also explicitly name the parent group in the

constructor (see the API notes). Methods such as activeCount and interrupt refer to all threads in

their group and all child groups.

  • Thread(ThreadGroup g, String name)

creates a new Thread that belongs to a given ThreadGroup.

  • ThreadGroup getThreadGroup()

returns the thread group of this thread.

  • ThreadGroup(String name)

creates a new ThreadGroup. Its parent will be the thread group of the current thread.

java.lang.Thread 1.

java.lang.Thread 1.

Parameters: g^ The thread group to which the new thread belongs

name The name of the new thread

java.lang.ThreadGroup 1.

Parameters: name^ The name of the new thread group