public class MoreMethods
{
public static
void main(String args[])
{
Thread t1 = new Thread();
System.out.println("t1 name by default: " + t1.getName()); // given
Thread-0
t1.setName("tax");
System.out.println("t1 name after a name is given: " + t1.getName()); // gives
tax
System.out.println("t1 priority by default: " + t1.getPriority()); //
prints 5
System.out.println("Thread group t1 default:" + t1.getThreadGroup()); // pints main
t1.setPriority(Thread.NORM_PRIORITY+3);
System.out.println("t1 priority after setting: " + t1.getPriority()); //
8
System.out.println("t1 is daemon by default: " + t1.isDaemon()); //
false
t1.setDaemon(true);
System.out.println("After making daemon, t1 is daemon: " + t1.isDaemon()); //
true
System.out.println("t1 is alive: " +
t1.isAlive()); //
false
System.out.println("t1 is interrupted: " + t1.isInterrupted()); //
false
}
}
|
A thread by
default, at the time of brith, comes with three properties which can be changed
by the programmer if needed.
- Name: Every thread created gets by
default a name. The first thread created gets Thread-0, the next
one as Thread-1 and so on. With setName() method, a thread
can be given a name and with getName() method, a thread's name can
be retrieved.
- Priority: Every thread created gets by
default a priority of 5, known as NORM_PRIORITY. A thread can be given a
priority with setPriority() method and a thread's priority can be
retrieved with getPriority() method.
- ThreadGroup: Every thread created should
belong to some thread group. A thread group should be assigned to a thread
at the time of creating the thread itself. If the programmer does not
mention any group, the thread is placed in the default main group.
Once a thread group is assigned, it cannot be reassigned to another group
later. ThreadGroup is a class from java.lang package.
isAlive() method returns a boolean value. A
programmer can create a number of threads of which a few may be active, some
inactive and the other might have dead. To know the state of a thread, a
programmer can use isAlive() method. This method returns true if the thread is
in runnable state or blocked state. In born state and dead state, the method
returns false.
isInterrupted() method returns true if the thread
state (like execution or blocked time) is disturbed.
Daemon
Threads
Daemon
threads are service-oriented threads. A service-oriented thread, as the
name indicates, serves all other threads. They die after every thread in the
process dies, or to say, just before the process exits (no way related with the
run() method execution). They are created before any thread is created and dies
after every thread dies. For example, the JVM comes with a service thread, garbage
collector which removes the garbage (unwanted objects etc.) generated while
the process is going on.
The daemon
threads are given lowest priority as they should come into action when no other
thread is active as process execution (that gives output) must be of highest
priority. A normal thread can be converted into a daemon thread with the
following simple statement.
t1.setDaemon(true);
The boolean
value true indicates t1 should be converted into a daemon thread.
If false or if the statement is completely omitted, the thread is a
non-daemon thread.
ThreadGroup
We know earlier, every thread should
belong to some thread group and if no group is mentioned, the thread is placed,
by default, in main thread group. When the JVM starts a new process, it
creates main thread group and every thread created by the programmer, if not
mentioned any group, the JVM keeps the thread in the main thread group. The
programmer can explicitly mention a thread group also where the thread is to be
placed. But remember, the thread should be placed in a group at the time of
creating the thread only; else it is placed in main thread group implicilty.
Once a thread is allotted a thread group, throughout its life, the group cannot
be changed.
By placing the thread in a group,
the advantage is, the thread attains the properties of the group implicitly.
For example, any thread belonging to main thread group attains a default
priority of 5 because main group priority is set to 5. The java.lang
package includes ThreadGroup class to manipulate the threads with
groups.
Placing
Threads in ThreadGroup
With the
above knowledge of thread groups, now let us write a program where a thread is
created, placed in a group and its properties are set explicitly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class ThreadGroupInfo
{
public static
void main(String args[])
{
ThreadGroup tg1 =
new ThreadGroup("FinanceGroup");
System.out.println("tg1 name: " +
tg1.getName());
System.out.println("tg1 parent group: " + tg1.getParent());
System.out.println("tg1 priority, by default: " + tg1.getMaxPriority());
tg1.setMaxPriority(Thread.NORM_PRIORITY+3);
System.out.println("tg1 priority after setting: " + tg1.getMaxPriority());
System.out.println("Active threads in the tg1 group: " + tg1.activeCount());
Thread t1= new Thread(tg1,"RevenueThread");
System.out.println("Thread t1 Name:
" + t1.getName());
System.out.println("t1 group: " +
t1.getThreadGroup());
}
}
|
ThreadGroup
tg1 = new ThreadGroup(“FinanceGroup”);
A thread
group by name FinanceGroup is created. The programmer can retrieve the
name of the group with getName() method. getParent() method
returns the parent thread group of FinanceGroup. Any group created by the
programmer is placed in main thread group by the JVM implicitly. This is how the
JVM controls the user-defined thread groups. getMaxPriority() returns
the maximum priority, the threads of a group can be assigned. Observe the
screenshot, even though the default priority of main group is set to 5
implicitly by JVM, the programmer can assign to a maximum of 10 to a thread.
Using setMaxPriority() method, the programmer can assign a priority to a
group. In the program it is set to 8 (5+3). The activeCount() method
returns the number of active threads in the group. It printed zero in the program
as we did not place any threads in the group and started.
Thread t1=
new Thread(tg1,"RevenueThread");
In the above
statement, a thread by name t1 is created with name RevenueThread
and is placed in the group tg1. It must be observed that a thread should
be placed in a group at the time of creation itself; else, it is placed in main
group and once placed in a group, it cannot be changed.
Advantages
of ThreadGroup
It is learnt
earlier that every thread should belong to a group. With thread group, all the
threads in a group can be assigned properties at a time instead of the
laborious way of setting property to each individual thread separately.
Following are the benefits with thread groups.
- All the threads can be given a
common priority. For example, the common priority set to all the threads
of main group is 5.
- All the threads of a group can
be stopped, suspended or resumed at a time, but cannot be started at a
time ; each individual thread should be started separately.
Generally,
thread groups are used very less in programming. The programmer leaves the
thread management to the JVM itself. SecurityManager class should be
used to have extra control or manipulation over the thread groups.
1. Creating Heavyweight Threads
We know earlier, multithreading is
nothing but executing multiple threads simultaneously. In the following
program, two threads of different classes, Test1 and Test2 are
created and executed. One thread prints the numbers in ascending order and the
other in descending order, alternatively. As these threads belong to two
different classes, it is an example of heavyweight process.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
class Test1 extends Thread
{
public void
run()
{
for(int i = 0; i < 10; i ++)
{
System.out.println("Test1: "
+ i);
try
{
Thread.sleep(1000);
}
catch(InterruptedException
e)
{
e.printStackTrace();
}
}
}
}
class Test2 extends Thread
{
public void
run()
{
for(int i = 9; i >= 0; i--)
{
System.out.println("Test2: "
+ i);
try
{
Thread.sleep(1000);
}
catch( InterruptedException
e )
{
e.printStackTrace();
}
}
}
}
public class
TwoRuns
{
public static
void main(String args[])
{
Test1
t1 =
new Test1();
Test2
t2 =
new Test2();
t1.start();
t2.start();
try
{
t1.join();
t2.join();
}
catch( InterruptedException e )
{
e.printStackTrace();
}
}
}
|
f="http://way2java.com/wp-content/uploads/2011/03/ss.bmp">

The t1
prints 0 and becomes inactive for 1000 milliseconds by calling sleep()
method. As the microprocessor does not have any work (or idle), it allocates
its time to the waiting thread t2. t2 prints 9 and goes for sleep
for 1000 milliseconds. Meantime, t1 comes out of sleep time, becomes
active, prints 1 and again goes for sleep. Then t2 awakes, prints 8 and
goes for sleep. Like this, the two loops managed by two threads (belonging to
two different processes), t1 and t2, print the numbers
alternatively. At any time given, only one thread is active and all the
remaining are inactive. You can change the sleep timings and find the
difference in output.

Observe, when t1 is active, t2 is inactive and when t2 is active, t1 is inactive. sleep() method is the easiest way, a programmer can shift the execution control from one thread to the other. Other methods also exist, but to activate an inactive thread, it requires an extra method call; this we get later.
Note
: At
different times of execution, you may see t2 starts first even though t1 is
started first. It wholly depends on your processor speed and time availability.
t1.join();
One thread
creates the other. The first thread, implicitly created and executed at the
beginning of the process, is main thread. For us, main() is a method,
but internally it is a thread. Do not get confused, there is a thread group on
the name of main; this we get later. In the above program, main thread created
t1 and t2 threads. main thread is known as parent thread and t1
and t2 are known as child threads. Here, the parent thread is main and
it need not be the main, it can be another thread also. In multithreaded
programming, the programmer should see that child thread dies first and then
its creator, parent thread. If not, t1 and t2 become orphan threads and
output may differ (again depends on the processor speed). Then, how to make the
parent thread to die always later than the child. Call simply join()
method on the child thread. join() method is an instruction to the JVM
to see that parent thread should not be allowed to die before child dies, even
if the parent thread completes its job early.
No comments:
Post a Comment