Notes on Threads - Organization, Programming, Language | CMSC 330, Study notes of Programming Languages

Material Type: Notes; Class: ORGNZTN PROGM LANG; Subject: Computer Science; University: University of Maryland; Term: Unknown 1989;

Typology: Study notes

Pre 2010

Uploaded on 02/13/2009

koofers-user-mvq
koofers-user-mvq 🇺🇸

10 documents

1 / 24

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CMSC 330: Organization of
Programming Languages
Threads
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18

Partial preview of the text

Download Notes on Threads - Organization, Programming, Language | CMSC 330 and more Study notes Programming Languages in PDF only on Docsity!

CMSC 330: Organization of

Programming Languages

Threads

Deadlock

• Deadlock occurs when no thread can run

because all threads are waiting for a lock

  • (^) No thread running, so no thread can ever release a

lock to enable another thread to run

Thread 1

l.lock(); m.lock(); ... m.unlock(); l.unlock();

Lock l = new ReentrantLock(); Lock m = new ReentrantLock(); Thread 2

m.lock(); l.lock(); ... l.unlock(); m.unlock();

This code can

deadlock…

-- when will it work?

-- when will it

deadlock?

Wait Graphs

l T1 Thread T1 holds lock l

T2 m

Thread T2 attempting to

acquire lock m

Deadlock occurs when there is a cycle in the graph

Wait Graph Example

l T

T2 m

T1 holds lock on l

T2 holds lock on m

T1 is trying to acquire a lock on m

T2 is trying to acquire a lock on l

Solution: Use Finally

static Lock l = new ReentrantLock();

void f () throws Exception { l.lock(); try { FileInputStream f = new FileInputStream("file.txt"); // Do something with f f.close(); } finally { // This code executed no matter how we // exit the try block l.unlock(); } }

Synchronized

• This pattern is really common

  • (^) Acquire lock, do something, release lock under any

circumstances after we’re done

  • (^) Even if exception was raised etc.

• Java has a language construct for this

  • (^) synchronized (obj) { body }
    • (^) Every Java object has an implicit associated lock
  • (^) Obtains the lock associated with obj
  • (^) Executes body
  • (^) Release lock when scope is exited
    • (^) Even in cases of exception or method return

Discussion

• An object and its associated lock are different!

  • (^) Holding the lock on an object does not affect what

you can do with that object in any way

  • (^) Ex: synchronized(o) { ... } // acquires lock named o o.f (); // someone else can call o’s methods o.x = 3; // someone else can read and write o’s fields

object o

o’s lock

Example: Synchronizing on this

• Does this program have a data race?

  • (^) No, both threads acquire locks on the same object

before they access shared data

class C { int cnt;

void inc() { synchronized (this) { cnt++; } } }

Thread 1 c.inc();

Thread 2 c.inc();

C c = new C();

Example: Synchronizing on this (cont’d)

• Does this program have a data race?

  • (^) No, threads acquire different locks, but they write to

different objects, so that’s ok

class C { int cnt;

void inc() { synchronized (this) { cnt++; } } }

Thread 1 c1.inc();

Thread 2 c2.inc();

C c1 = new C(); C c2 = new C();

Synchronized Methods

• Marking method as synchronized same as

synchronizing on this in body of the method

  • (^) The following two programs are the same

class C { int cnt;

void inc() { synchronized (this) { cnt++; } } }

class C { int cnt;

synchronized void inc(){ cnt++; } }

Synchronized Static Methods

• Warning: Static methods lock class object

  • (^) There’s no this object to lock

class C { static int cnt;

void inc() { synchronized (this) { cnt++; } }

static synchronized void dec() { cnt--; } }

Thread 1 c.inc();

Thread 2 C.dec();

C c = new C();

What can be synchronized?

• code blocks

• methods

  • (^) subclasses do not inherit synchronized keyword
  • (^) interface methods cannot be declared synchronized

• NOT fields

  • (^) but you could write synchronized accessor methods

• NOT constructors

  • (^) but you could include synchronized code blocks

• objects in an array

Thread Lifecycle

• While a thread executes, it goes through a

number of different phases

  • (^) New : created but not yet started
  • (^) Runnable : can run on a free CPU
  • (^) Running : currently executing on a CPU
  • (^) Blocked : waiting for I/O or on a lock
  • (^) Sleeping : paused for a user-specified interval
  • (^) Terminated : completed

Which Thread to Run Next?

• Look at all runnable threads

  • (^) A good choice to run is one that just became

unblocked because

  • (^) A lock was released
  • (^) I/O became available
  • (^) It finished sleeping, etc.

• Pick a thread and start running it

  • (^) Can try to influence this with setPriority(int)
  • (^) Higher-priority threads get preference
  • (^) But you probably don’t need to do this