Java Threading: Creating, Managing, and Synchronizing Threads - Prof. Mark Weiss, Study notes of Computer Science

An overview of java threading, including the concept of multitasking, threads, thread classes, creating and running threads, thread states, and thread methods. It covers the importance of synchronization and deadlock avoidance, as well as common mistakes and best practices.

Typology: Study notes

Pre 2010

Uploaded on 09/17/2009

koofers-user-0o2-1
koofers-user-0o2-1 🇺🇸

8 documents

1 / 28

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
1
Threads and Synchronization
Mark Allen Weiss
Copyright 2000
2
Outline of Topics
What threads are
The
Thread
Synchronization: keeping threads from
clobbering each other
Deadlock avoidance: keeping threads from
stalling over each other
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c

Partial preview of the text

Download Java Threading: Creating, Managing, and Synchronizing Threads - Prof. Mark Weiss and more Study notes Computer Science in PDF only on Docsity!

1

Threads and Synchronization

Mark Allen Weiss

Copyright 2000

2

Outline of Topics

l What threads are

l The Thread class and starting some threads

l Synchronization: keeping threads from

clobbering each other

l Deadlock avoidance: keeping threads from

stalling over each other

3

Multitasking

l Multitasking means that you can have several

processes running at same time, even if only

one processor.

l Can run a browser, VM, powerpoint, print job,

etc.

l All modern operating systems support

multitasking

l On a single processor system, multitasking is

an illusion projected by operating system

4

Threads

l Inside each process can have several threads

l Each thread represents its own flow of logic

  • gets separate runtime stack

l Modern operating systems support threading

too; more efficient than separate processes

l Example of threading in a browser:

  • separate thread downloads each image on a page

(could be one thread per image)

  • separate thread displays HTML
  • separate thread allows typing or pressing of stop

button

  • makes browser look more responsive

7

l VM has threads in background

l VM alive as long as a “legitimate thread” still

around (illegitimate threads are “daemons”)

l GUI programs will start separate thread to

handle events once frame is visible

main thread

garbage collector

event thread

(once container is visible)

Threads in the Virtual Machine

8

Thread Class

l Use Thread class in java.lang

l Two most important instance methods:

  • start : Creates a new thread of execution in the

VM; then, invokes run in that thread of execution;

current thread also continues running

  • run : explains what the thread should do

l Thread is not abstract, so there are default

implementations

  • start does what is described above; should be final

method (but isn’t)

  • run returns immediately

9

Creating A Do Nothing Thread

l The following code creates a Thread object,

then starts a second thread.

public static void main( String[] args ) {

Thread t = new Thread( );

t.start( ); // now two threads, both running

System.out.println( “main continues” );

}

l In code above:

  • First line creates a Thread object, but main is the

only running thread

  • Second line spawns a new VM thread. Two threads

are now active.

  • main thread continues at same time as new thread

calls its run method (which does nothing)

10

Getting Thread to Do Something

l Option #1: extend Thread class, override run

method

class ThreadExtends extends Thread {

public void run( ) {

for( int i = 0; i < 1000; i++ )

System.out.println( "ThreadExtends " + i );

}

}

class ThreadDemo {

public static void main( String[] args ) {

Thread t1 = new ThreadExtends( );

t1.start( );

for( int i = 0; i < 1000; i++ )

System.out.println( "main " + i );

}

}

13

Anonymous Implementation

l May see the Runnable implemented as an

anonymous class in other people’s code

class ThreadDemo {

public static void main( String[] args ) {

Thread t3 = new Thread ( new Runnable( ) {

public void run( ) {

for( int i = 0; i < 1000; i++ )

System.out.println( "ThreadAnonymous " + i );

}

}

);

t3.start( );

for( int i = 0; i < 1000; i++ )

System.out.println( "main " + i );

}

}

14

Common Mistake #

l You should NEVER call run yourself

will not create new VM thread

  • will not get separate stack space
  • will invoke run in the current thread

l start don’t run

15

Thread States

l Thread is not runnable until start is called

l Thread can only unblock if cause of blocking is

resolved

new

dead

runnable

blocked

start

constructor

sleep, wait, blocked on I/O

time expires, notifyAll, I/O complete

run terminates

16

Is The Thread Alive?

l Cannot differentiate between being runnable

and blocked.

l Thread that is runnable or blocked is alive

l Thread that has not started or is dead is not

alive

l Can use Thread instance method isAlive to

determine thread status

19

Current Thread

l Before you can invoke any Thread instance

method, you need a reference to the current

thread

If you extend Thread , no problem. In your run

method, this represents current Thread and can

be omitted

If you use Runnable , in your run method this

represents the Runnable object. Need to use static

method Thread.currentThread

Thread self = Thread.currentThread( );

20

Deamon Threads

l By themselves do not keep a VM alive

l Can mark a thread as a daemon thread by

calling setDaemon(true)

l Call must be before call to start ; after call an

exception is thrown

l Without call to setDaemon thread’s daemon

status is same as thread that spawned it

l Can call isDaemon to see if thread is a

daemon

21

Thread Priorities

l Can suggest to VM that when there is

contention for CPU, some threads should get

preference over others.

  • Only considered when there’s CPU contention;

threads that are sleeping won’t go any faster with

higher priorities

  • If your program depends on priorities, you need to

do more work; VM could ignore suggestions

  • Priority of thread is same as thread that created it
  • Only 10 priorities ranging from

Thread.MIN_PRIORITY to

Thread.MAX_PRIORITY , with

Thread.NORM_PRIORITY

22

Current Implementations

l Windows 98/NT and Solaris Native Threads:

schedule highest priority thread

  • scheduling is fully preemptive: if a new highest

priority thread becomes runnable, it gets scheduled

rule of thumb: at any given time, highest-priority

thread is running. But this is not guaranteed by

language spec.

Java platform does not time-slice, underlying thread

platform does (Solaris Green Threads does not), so

if several highest priority threads, system generally

does simple, non-preemptive round-robin

25

join

l The call t1.join( ) causes the current

thread to block until t1 terminates

l Have to catch InterruptedException

l main can join on all threads it spawns to wait

for them all to finish

26

yield

l Threads that are CPU intensive can hog all the

cycles, especially if they are high priority

l Polite thread yields every now and then

  • not too often; could be spending too much time

context switching

yield

is a static method.

l Current thread

  • Gives up the processor if another thread of at least

as high priority is waiting for the CPU

  • If no eligible thread, current thread retains

processor

l Must catch InterruptedException

27

sleep

l Static method.

l Current thread

  • Gives up the processor for at least the time specified
  • Time is in milliseconds
  • No guarantee that you get processor back

l Must catch InterruptedException

28

Timeouts

l can invoke wait and join with a parameter

that limits the amount of blocking (in

milliseconds)

for wait not necessarily a great idea

l Example: thread needs to do I/O; what if

nothing is typed?

Do I/O in a separate thread

  • main thread does a join , with timeout on the I/O

thread

  • If no I/O, main thread will continue and can

terminate itself and I/O thread if needed

31

Two Mutators Do Serious Damage

l Last example not so bad

We temporarily see object in a bad state

  • Thread 1 gets time-sliced in and object gets back in

good state

Often we view objects in bad states, and we know

that current information may be inaccurate, but will

eventually be correct

l bank accounts

l frequent flyer accounts

l credit card statements

l When two mutators interact, can irreversibly

damage object state

32

Two mutators

class TwoObjs {

private int a = 15;

private int b = 37;

public int sum( ) { return a + b; } // should always be 52

public void swap( ) { int tmp = a; a = b; b = tmp; }

}

l Starting from good state

  • Thread 1 invokes swap , and immediately after

executing tmp=a is time-sliced out. In this thread

tmp= .

  • Thread 2 invokes swap , swapping a and b. a is now

37, b is now 15.

Thread 1 is time-sliced back in and continues: a is

now 15,

b is now

tmp , so

b is 15. OOPS!

33

Can This Really Happen?

l Yes but,

It can be fairly rare

  • Depends on speed of processors
  • Depends on number of processors

Depends on thread priorities

Depends on luck of the draw

l Worst kind of bug

  • TwoObjs class is not thread-safe
  • Could do millions of operations and never see a

problem

  • Hard to know you’ve messed up

34

How Java Solves The Problem

l Use the synchronized keyword

l Marking an instance method as synchronized

means that in order to invoke it the thread

must gain possession of the “monitor” for the

invoking object (i.e. the “monitor” for this ).

l The monitor is an abstraction

every object has one and only one

  • no getMonitor method, however

37

Example #

l Assume both print and swap are synchronized

  • Thread #1 does obj.swap( )

l can obtain obj ’s monitor and enter

  • Thread #1 is timesliced out in the middle of swap

l Thread #1 holds on to obj

’s monitor

  • Thread #2 does obj.print()

l Thread #2 needs obj ’s monitor. Can’t get it, so thread is

blocked

Thread #1 is timesliced in; finishes swap

l Thread #1 releases obj ’s monitor

  • Thread #3 does obj.print()

l Thread #3 gets the monitor and proceeds

38

Example #

l Assume only swap is synchronized

  • Thread #1 does obj.swap( )

l can obtain obj ’s monitor and enter

  • Thread #1 is timesliced out in the middle of swap

l Thread #1 holds on to obj

’s monitor

  • Thread #2 does obj.print()

l Thread #2 does not need obj ’s monitor, so it proceeds

Thread #1 is timesliced in; finishes swap

l Thread #1 releases obj ’s monitor

39

Example #

l Assume swap is synchronized, and obj1 and

obj2 are different objects

  • Thread #1 does obj1.swap( )

l can obtain obj1 ’s monitor and enter

  • Thread #1 is timesliced out in the middle of swap

l Thread #1 holds on to obj

’s monitor

  • Thread #2 does obj2.print()

l can obtain obj2 ’s monitor and enter, so it proceeds

l when it finishes it releases obj

’s monitor

  • Thread #1 is timesliced in; finishes swap

l Thread #1 releases obj1 ’s monitor

40

Static Methods

l Synchronized static methods require the

obtaining of a monitor also

can’t be the objects monitor because there is not

  • the monitor it needs to obtain the monitor for the

Class object.

l May be important for fancy stuff

l Just remember that instance methods and

static methods use different monitors