Download Review03-AnnotationThreads

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java Programming II
Annotations and Reflection
Java Threads
Java Programming II
1
Contents










Annotations
Annotating Elements
Restricting Annotation Applicability
Retention Policies
The Class Class
Examples
Reflection
Annotation Queries
The Modifier Class
The Member classes
Java Programming II
2
Annotations
 The source code for our program is usually accompanied by copious
amounts of informal documentation that typically is contained within comments
in the source code
 Many organizations have a standard preamble: copyright information,
the programmers name, the date the class was created, etc.
 Other comments by external tools: version control in a source code
management system, or deployment descriptors on how a class should be
managed by an application server.
 Comments based annotation
 A better way to document the many annotations: to annotate the
program elements directly using annotation types
 Another motivation: many APIs require a fair amount of boilerplate
code. (For example, in order to write a JAX-RPC web service, you
must provide a paired interface and implementation. ) This boilerplate
could be generated automatically by a tool if the program were
“decorated” with annotations indicating which methods were remotely
accessible.
Java Programming II
3
Annotations
 Provide data about a program that is not part of the
program itself.
 Using annotation type to describe the form of the
annotations.
 Uses of Annotation
Information for the compiler — Annotations can be used
by the compiler to detect errors or suppress warnings.
Compiler-time and deployment-time processing —
Software tools can process annotation information to
generate code, XML files, and so forth.
Runtime processing — Some annotations are available
to be examined at runtime.
Java Programming II
4
Annotations
Documentation
Annotation Type
Using Annotation
Using Comments
/*-----------------------------Created: Jan 31 2005
Created By: James Gosling
Last Modified: Feb 9 2005
Last Modified By: Ken Arnold
Revision: 3
---------------------------------*/
public class Foo {
// …..
}
How to use Annotation
1. Define Annotation Type
2. Add Annotation using the
type
@interface ClassInfo {
String created();
String createdBy();
String lastModified();
String lastModifiedBy();
int revision();
}
@ClassInfo(
created = “Jan 31 2005”,
createdBy = “James Gosling”,
lastModified =“Feb 9 2005”,
lastModifiedBy =“Ken Arnold”,
revision =3
) public class Foo {
// class definition…
Annotation for the
}
class Foo
Java Programming II
5
Annotation Types
 Constraint rules of the methods declared in an annotation type (elements
of annotation type)
 The type of the element can only be a primitive type, String , enum, another
annotation type, Class, or an array of the preceding types.
 Cannot declare any parameters.
 Cannot have a throws clause.
 Cannot define a type parameter, i.e cannot be a generic method.
@interface Revision {
int major() default 1;
int minor() default 0;
}
@interface ClassInfo {
String created();
String createdBy();
String lastModified();
String lastModifiedBy();
Revision revision();
}
Initialization expression
@ClassInfo (
created = “Jan 31 2005”,
createdBy = “James Gosling”,
lastModified = “Feb 9 2005”,
lastModifiedBy = “Ken Arnold”,
revision = @Revision(major=3)
)
public class Foo {
// …
- Marker annotation: annotation type
}
which has zero elements
(ex) public @interface Preliminary { }
Java Programming II
6
Annotation Used by Complier
 @Deprecated—the @Deprecated
annotation indicates that the marked
element is deprecated and should no
longer be used. When an element is
deprecated, it should also be
documented using the Javadoc
@deprecated tag.
// Javadoc comment follows
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
}
 @Override—the @Override annotation informs the compiler that the
element is meant to override an element declared in a superclass
(overriding methods will be discussed in the the lesson titled "Interfaces
and Inheritance").
 @SuppressWarnings—the
@SuppressWarnings annotation tells the
compiler to suppress specific warnings that it
would otherwise generate . In the example of
the right site, a deprecated method is used
and the compiler would normally generate a
warning. In this case, however, the annotation
causes the warning to be suppressed.
@SuppressWarnings(deprecation)
void useDeprecatedMethod() {
objectOne.deprecatedMethod();
// deprecation warning suppressed
}
}
Java Programming II
7
Annotating Elements and Restricting Annotation
Applicability

Marker annotation or all its
elements have default
values
@Deprecated
public void badMethod() {/* … */}
 (an empty list of initializers)
@Deprecated()
public void badMethod() {/* … */}

Array initializer expression
@interface BugsFixed {
String[] bugIds();
}

@BugsFixed(bugIDs = {“1234”,
“4567”})
or
@BugsFixed(bugIDs = “4567”)

When has only a single
element (naming of the
element is value), it
allows for additional
shorthand:
@inteface BugsFixed {
String[] value();
}

@BugsFixed({“1234”,”4567”})
@BugsFixed(“4567”)
Java Programming II
8
Retention Policies

Annotation can serve many
different purposes and may be
intended for different readers
(programmers, or a development tool,
compiler, some tool that may need to
extract the annotations from a binary
representation of a class, and to be
inspected at runtime)


The Target annotation type
Enum constant of ElementType
: Represents the different kinds of
program elements to which
annotations can be applied.




ANNOTATION_TYPE : Annotation
type declaration
CONSTRUCTOR : Constructor
declaration
FIELD : Field declaration (includes
enum constants)
LOCAL_VARIABLE : Local variable
declaration




METHOD : Method declaration
PACKAGE : Package declaration
PARAMETER : Parameter declaration
TYPE : Class, interface (including
annotation type), or enum
declaration
 Example
@Target (ElementType.TYPE)
@interface ClassInfo {
String created();
String createdBy();
This will be
String lastModified();
applied to
type
String lastModifiedBy();
declaration
Revision revision();
}
Java Programming II
9
Retention Policies

Three Retention Policies
Can be applied when the annotation can be accessed.
(Used by @Retention type, Defined by the RetentionPolicy
enum)



SOURCE: Annotations exist only in the source file
CLASS: preserved in the binary representation of the class,
but not available at run time
RUNTIME: must be available at runtime via the reflection
mechanism
 Example
@Retention(RetentionPolicy.RUNTIME)
Java Programming II
10
The “Class” class

The Class class defines
these methods:




getName – returns the
(class) name
getFields – returns all the
public fields
getMethods – returns all the
public methods
getPackage – returns the
class’ package




Java Programming II
getSuperclass – returns the
class’ superclass
getConstructors – returns all
the public constructors
static Class<?>
forName(String className)
- returns Class object
Annotation[]
getAnnotations() - returns all
annotations present on this
element.
11
Working with Annotations (I)

A simple annotation-based test framework
“RunTests.java”
import java.lang.reflect.*;
“Foo.java”
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Test { }
public class RunTests {
public static void main(String[] args) throws
Exception {
int passed = 0, failed = 0;
for (Method m :
Class.forName(args[0]).getMethods()) {
Add “Test”
public class Foo {
if (m.isAnnotationPresent(Test.class)) {
Annotation
@Test public static void m1() { }
try {
public static void m2() { }
m.invoke(null);
@Test public static void m3() {
passed++;
throw new RuntimeException("Boom");
} catch (Throwable ex) {
}
System.out.printf("Test %s failed: %s %n",
public static void m4() { }
m, ex.getCause());
@Test public static void m5() { }
failed++;
public static void m6() { }
}
@Test public static void m7() {
}
throw new RuntimeException("Crash");
}
}
System.out.printf("Passed: %d, Failed %d%n",
public static void m8() { }
passed, failed);
}
}
}
Run:
% java RunTests Foo
Java Programming II
12
Working with Annotations (II)

BugsFixedExample: Using Class
and getAnnotation method of the
“ClassInfo” class
“MyFoo.java”
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface BugsFixed {
String[] value();
}
@BugsFixed( {"1234", "5678"} )
public class MyFoo {
}
“BugsFixedExample.java”
public class BugsFixedExample {
public static void main(String[] args) {
Class<MyFoo> cls = MyFoo.class;
BugsFixed bugsFixed =
(BugsFixed)
cls.getAnnotation(BugsFixed.class);
System.out.println(bugsFixed);
String[] bugIds = bugsFixed.value();
for (String id : bugIds)
System.out.println(id);
}
}
Run:
% java BugsFixedExample
Java Programming II
13
Documentation Comments

A Simple Example
/**
* An <code>Attr</code> object defines an attribute as a
* name/value pair, where the name is a <code>String</code>
* and the value an arbitray <code>Object</code>.
*
* @version 1.1
* @author Plago
* @since 1.0
*/
public class Attr {
/** The attribute name. */
private final String name;
/** The attribute value. */
private Object value = null;
/** Returns this attribute's name. */
public String getName() {
return name;
}
/** Returns this attribute's value. */
public Object getValue() {
return value;
}
/**
* Sets the value of this attribute. Changes the
* value returned by calls to {@link #getValue}.
* @param newValue The new value for the attribute.
* @return The Original value.
* @see #getValue()
*/
public Object setValue(Object newValue) {
Object oldVal = value;
value = newValue;
return oldVal;
}
/**
* Crates a new attribute with the given name and an
* initial value of <code>null</code>.
* @see Attr#Attr(String,Object)
*/
public Attr(String name) {
this.name = name;
}
/**
* Creates a new attribute with the given name and
* inital value.
* @see Attr#Attr(String)
*/
public Attr(String name, Object value) {
this.name = name;
this.value = value;
}
/**
* Returns a string of the form <code>name=value</code>.
*/
public String toString() {
return name + "='" + value + "'";
}
}
Run:
% javadoc Attr.java
Java Programming II
14
Reflection

The reflection is to
examine a type in detail.



The reflection package :
java.lang.reflect
Reflection starts with a
Class object
A simple example of a
“type browser”.
Argument:
import java.lang.reflect.*;
import static java.lang.System.out;
import static java.lang.System.err;
public class SimpleClassDesc {
public static void main(String[] args) {
Class type = null;
try {
type = Class.forName(args[0]);
} catch(ClassNotFoundException e) {
err.println(e);
return;
}
Attr.class
out.print("class " + type.getSimpleName());
Class superclass = type.getSuperclass();
if (superclass != null)
out.println(" extends " +
superclass.getCanonicalName());
else out.println();
Run:
% java SimpleClassDesc Attr
Result:
class Attr extends java.lang.Object
public java.lang.String Attr.getName()
public java.lang.String Attr.toString()
public java.lang.Object Attr.getValue()
public java.lang.Object Attr.setValue(java.lang.Object)
Method[] methods = type.getDeclaredMethods();
for (Method m : methods)
if (Modifier.isPublic(m.getModifiers()))
out.println(" " + m);
}
}
The source code is at the /home/course/java2/code/AnnotationReflection/
Java Programming II
15
The Introspection Hierarchy
Type
ParameterizedType
GenericArrayType
TypeVariable<D>
AnnotatedElement
WildcardType
AccessibleObject
GenericDeclaration
Member
Class
Constructor
Method
Java Programming II
Field
Package
16
Type Tokens
 Type Token



Each Class object for a
reference type is of a
parameterized type
corresponding to the class it
represents. (Ex: the type of
String.class is Class<String>)
A parameterized Class type is
known as the type token for a
given class
The easiest way to obtain a
type token is to use a class
literal.
class literal
import java.util.*;
public class TypeTokenTest {
public static void main(String[] args) {
Class<String> c1 = String.class;
System.out.println("Result1 = " + c1.getClass());
String str = "Hello";
// Class<String> c2 = str.getClass(); // error!
Class<? extends String> c2 = str.getClass();
System.out.println("Result2 = " + c2);
try {
Class<?> c3 =
Class.forName("java.lang.String"); //valid
Class<? Extends String> c3 =
Class.forName("java.lang.String"); //invalid
System.out.println("Result3 = " + c3);
} catch(ClassNotFoundException e) {
System.err.println(e); return;
}
Exact type token
How about this?
}
}
Class<? extends String> c3 =
Class.forName("java.lang.String").asSubclass(String.class);
Java Programming II
17
Class Inspection
import java.lang.reflect.*;
public class TypeDesc {
public static void main(String[] args) {
TypeDesc desc = new TypeDesc();
for (String name : args) {
try {
Class<?> startClass = Class.forName(name);
desc.printType(startClass, 0, basic);
} catch (ClassNotFoundException e) {
System.err.println(e); // report the error
}
}
}
// by default print on standard output
private java.io.PrintStream out = System.out;
// used in printType(U) for labeling type names
private static String[]
basic = {"class", "interface", "enum", "annotation"},
supercl = {"extends", "implements"},
iFace = {null, "extends"};
private void printType(
Type type, int depth, String[] labels) {
if (type == null) // stop recursion -- no supertype
return;
// turn the Type into a Class object
Class<?> cls = null;
if (type instanceof Class<?>) {
cls = (Class<?>) type; }
else if (type instanceof ParameterizedType) {
cls = (Class<?>)
((ParameterizedType)type).getRawType(); }
else
throw new Error("Unexpected non-class type");
Get type
token
// print this type
for (int i = 0; i < depth; i++)
out.print(" ");
int kind = cls.isAnnotation() ? 3 :
cls.isEnum() ? 2 :
cls.isInterface() ? 1 : 0 ;
out.print(labels[kind] + " ");
out.print(cls.getCanonicalName());
// print generic type parameters if present
TypeVariable<?>[] params = cls.getTypeParameters();
if (params.length > 0) {
out.print('<');
for(TypeVariable<?> param : params) {
out.print(param.getName());
out.print(", ");
}
out.println("\b\b>");
}
else out.println();
// print out all interfaces this class implements
Type[] interfaces = cls.getGenericInterfaces();
for (Type iface : interfaces) {
printType(iface, depth + 1,
cls.isInterface() ? iFace : supercl);
}
// recurse on the superclass
printType(cls.getGenericSuperclass(),
depth + 1, supercl);
} // end of main
} // end of clss
The source code is at the /home/course/java2/code/AnnotationReflection/Reflection
Java Programming II
18
Class Inspection
Run:

% java TypeDesc
java.util.HashMap

Result:
class java.util.HashMap<K, V>
implements java.util.Map<K, V>
implements java.lang.Cloneable
implements java.io.Serializable
extends java.util.AbstractMap<K,
V>
implements java.util.Map<K, V>
extends java.lang.Object


Examining the kind of
Class object
Ask whether have a toplevel type or a nested type,
and if nested, some
information about which
kind of nested type
Find out where a type fits
in the type hierachy
Apply to a subset of those
different kinds.
Java Programming II
19
Java Programming II
Java Threads
Java Programming
20
Contents
What
is Thread?
Creating Threads
 Using Runnable
 Sleep, Interrupt, and Join
Methods
 Synchronization
Java Programming
21
Contents
Synchronized statements
 wait, notifyAll, and notify Methods
 A Producer and Consumer
Example
 Thread Scheduling

Java Programming
22
Concurrent Programming
 Two basic units in concurrent programming: Processes and Threads. Java
Programming is mostly concerned with threads.
 A thread is called a sequence of steps executed on at a time.
 The single threaded programming model is the one most programmers use.
The multithreading is called the analogue to having multiple real-world bank
tellers.
bal = a.getBalance();
bal = b.getBalance();
bal += deposit ;
bal += deposit ;
a.setBalance(bal);
b.setBalance(bal);
“a” is a thread
object of some
bank
Java Programming
“b” is a thread
object of
another bank
23
An Overview of Threads

What is a Thread?

A sequence of execution within a process
 A Lightweight process – requires fewer
resources than processes
 JVM manages and schedules threads
 Possible States:
(1) new (2) ready (3) running (4) waiting
(5) dead
Java Programming
24
An Overview of Threads
 Thread life cycle
Dead
Sleep,wait,I/O
New
Ready
Running
Java Programming
Waiting
25
How to Create Threads
 Creating a Thread Object
Thread worker = new Thread();
 Two ways
 Using the Thread Class
 Using the Runnable
interface
 Using the Thread Class
Extend the Thread class
Implement the run
method
public class PingPong extends Thread {
private String word;
private int delay;
public PingPong(String whatToSay, int
delayTime) {
word = whatToSay;
delay = delayTime;
}
public void run() {
try {
for(;;) {
System.out.print(word + “ “);
Thread.sleep(delay);
}
} catch (InterruptedException e) {
return;
}
}
public static void main(String[] args) {
new PingPong(“ping”, 33).start();
new PingPong(“PONG”,100).start();
}
}
Java Programming
26
Using Runnable
 Using Runnable Interface
 Create a Thread object to pass
object of implementation of the
Runnable interface into Thread
Constructor.
 Be useful when used with
other application such as GUI
or applet..
Implement Runnable Interface
Implement the run
method
Create Thread object
public class RunPingPong implements Runnable {
private String word;
private int delay;
public PingPong(String whatToSay, int delayTime) {
word = whatToSay;
delay = delayTime;
}
public void run() {
try {
for(;;) {
System.out.print(word + “ “);
Thread.sleep(delay);
}
} catch (InterruptedException e) {
return;
}
}
public static void main(String[] args) {
Runnable ping = new RunPingPong(“ping”, 33);
Runnable pong = new RunPingPong(“PONG”, 100);
new Thread(ping).start();
new Thread(pong).start();
}
}
Java Programming
27
Pausing Execution with Sleep
 Thread.sleep method causes
the current thread to suspend
execution for a specified period.
 Efficient means of making
processor time available to the
other threads of an application
or other applications that might
be running on a computer
system.
public class SleepMessages {
public static void main(String args[])
throws InterruptedException {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
for (int i = 0; i < importantInfo.length;
i++) {
//Pause for 4 seconds
Thread.sleep(4000);
//Print a message
System.out.println(importantInfo[i]);
}
 The sleep method can also be
used for pacing and waiting for
another thread with duties that
are understood to have time
requirements.
 Sleep Methods
}
 static void sleep(long millis)
}
 static void sleep(long millis, int
nanos)
Java Programming
It throws the
InterruptedException.
28
Join
 The join method allows one thread
to wait for the completion of
another.
t.join();
causes the current thread to pause
execution until t's thread terminates.
 Overloaded Methods
 void join() : Waits for this thread to
die.
 void join(long millis)
 void join(long millis, int nanos)
class ThreadM extends Thread {
public void run() {
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("ThreadM");
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
class ThreadN extends Thread {
public void run() {
try {
for (int i = 0; i < 20; i++) {
Thread.sleep(2000);
System.out.println("ThreadN");
}
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
}
join() method:
}
Waits for this thread to die.
class JoinDemo1 {
public static void main(String args[]) {
ThreadM tm = new ThreadM();
tm.start();
ThreadN tn = new ThreadN();
tn.start();
try {
tm.join();
tn.join();
System.out.println("Both threads have finished");
}
catch (Exception e) {
e.printStackTrace(); }
}
}
Java Programming
29
Interrupts
 An interrupt is an indication to
a thread that it should stop
what it is doing and do
something else.
 A thread sends an interrupt by
invoking the “interrupt()”
method on the Thread object
for the thread to be interrupted.
 Supporting Interruption
 If the thread is frequently invoking
methods that throw
InterruptedException, it simply
returns from the run method after it
catches that exception.
 Tests for the interrupt and exits the
thread if one has been received.
 In more complex applications, to
throw an InterruptedException
for (int i = 0; i < importantInfo.length; i++) {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
//We've been interrupted: no more
messages.
return;
}
System.out.println(importantInfo[i]);
}
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
//We've been interrupted: no more
crunching.
return;
}
}
if (Thread.interrupted()) {
throw new InterruptedException(); }
Java Programming
30
Example: SimpleThreads.java
try {
public class SimpleThreads {
//Display a message, preceded by the
name of the current thread
//Pause for 4 seconds
static void threadMessage(String
message) {
Thread.sleep(4000);
String threadName =
Thread.currentThread().getName();
System.out.format("%s: %s%n",
threadName, message);
}
private static class MessageLoop
implements Runnable {
String importantInfo[] = {
"Mares eat oats", "Does eat oats",
};
ThreadMessage(importantInfo[i]);
}
threadMessage("I wasn't done!"); }
} // end of run
} // end of
public static void main(String args[]) throws
InterruptedException {
public void run() {
"A kid will eat ivy too"
//Print a message
} catch (InterruptedException e) {
When this thread
receives an interrupt,
it happens.
"Little lambs eat ivy",
for (int i = 0; i < importantInfo.length; i++)
{
//Delay, in milliseconds before we
interrupt MessageLoop
//thread (default one hour).
long patience = 1000 * 60 * 60;
Java Programming
31
Example: SimpleThreads.java
//If command line argument present, gives
patience in seconds.
threadMessage("Waiting for MessageLoop thread
to finish");
if (args.length > 0) {
//loop until MessageLoop thread exits
try {
while (t.isAlive()) {
patience = Long.parseLong(args[0]) * 1000;
} catch (NumberFormatException e) {
System.err.println("Argument must be
an integer.");
System.exit(1);
threadMessage("Still waiting...");
//Wait maximum of 1 second for
MessageLoop thread to finish.
t.join(1000);
if (((System.currentTimeMillis() - startTime) >
patience) && t.isAlive()) {
}
When elapsed time is larger than
the patience, it send interrupt to
the thread “t”.
}
threadMessage("Tired of waiting!");
t.interrupt();
//Shouldn't be long now -- wait indefinitely
t.join();
threadMessage("Starting MessageLoop thread");
}
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
}
t.start();
threadMessage("Finally!");
}
}
The source code is at the “/home/course/java2/code/Thread/SimpleThreads.java”
Java Programming
32
Synchronization
 Synchronized Methods : protection from interference in a multithreaded
environment
acquire lock
wait to acquire lock
synchronized
method
release lock
acquire lock
synchronized
method
release lock
If one thread invokes a synchronized method on an object, the lock of that object
is first acquired, the method body executed, and then the lock released. Another
thread invoking a synchronized method on that same object will block until the
lock is released
Java Programming
33
Synchronized Methods

Example Code
public class BankAccount {
private long number; // account number
private long balance; // current balance (in cents)
public BankAccount(long initialDeposit) {
When a synchronized
balance = initialDeposit;
method is invoking, other
}
synchronized methods
in the class cannot be
synchronized public long getBalance() {
invoked, but nonreturn balance;
synchronized methods
}
can be invoked.
private final void setBalance(double amount) {
balance = amount;
}
synchronized public void deposit(double amount) {
double bal = getBalance();
bal += amount;
setBalance(bal);
*Example: Refer to the
}
“/home/course/java2/code/Thread/TellerTest.java”
// … rest of methods
}
Java Programming
34
Locking Objects with Synchronized Methods
thread 1
thread 2
thread 3
run() {
obj1.method2();
}
run() {
obj1.method3();
obj1.method1();
obj2.method1();
}
run() {
obj2.method3();
obj2.method2();
}
1
4
2
3
OK.
5
6
method1()
Not busy
obj 1
OK.
method2()
Not busy
synchronized
method1()
synchronized
method2()
method3()
obj 2
synchronized
method1()
No!
Not while method2()
for obj1 is executing
synchronized
method2()
No!
Always OK.
Not while method1()
for obj2 is executing
Java Programming
method3()
Always OK.
35
synchronized Statements

Synchronized Statements
 The synchronized
statement enables to
execute synchronized
code that acquires the
lock of any object, not
just the current object,
or for durations less
than the entire
invocation of a method.
To
execute
when
the lock
is
obtained.
synchronized (expr) {
statements
}
/** make all elements in the array
non-negative */
pubic static void abs(int[] values) {
synchronized (values) {
for (int i=0; i < values.length;
i++) {
if (values[i] < 0)
values[i] = -values[i];
}
The array is not changed
}
during execution by any other
}
code that is similarly
An
object
whose
lock is
to be
acquired
Java Programming
synchronized on the values
array
36
synchronized Statements
 A necessity of synchronize
statement
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
---
needs to synchronize
changes to lastName
and nameCount
also needs to avoid synchronizing
invocations of other objects' methods.
 In MsLunch, the c1 and c2, that
are never used together. All
updates of these fields must be
synchronized, but there's no
reason to prevent an update of c1
from being interleaved with an
update of c2 — and doing so
reduces concurrency by creating
unnecessary blocking.
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
Java Programming
37
synchronized Statements
 Advantages of the
synchronized statement



Can define a synchronized
region of code that is smaller
than a method.
Allow to synchronize on
objects other than this,
allowing a number of different
synchronization designs to be
implemented. A finer
granularity of locking.
Use for an inner object to
synchronize on its enclosing
object:
You can define
separate objects to be
used as locks for each
such group using
synchronized
statements
class SeparateGroups {
private double aVal = 0.0;
private double bVal = 1.1;
protected final Object lockA = new Object();
protected final Object lockB = new Object();
public double getA() {
synchronized(lockA) {
return aVal; }
}
public void setA(double val) {
synchronized (lockA) {
aVal = val; }
}
public double getB() {
synchronized(lockB) {
return bVal; }
}
public void setB(double val) {
synchronized (lockB) {
bVal = val; }
}
public void reset() {
synchronized (lockA) {
synchronized (lockB) {
aVal = bVal =
0.0;
}
}
}
}
Java Programming
38
Deadlock




Deadlock describes a situation where two or
more threads are blocked forever, waiting for
each other.
Alphonse and Gaston are friends, and great
believers in courtesy.
Bowing Rule: When you bow to a friend, you
must remain bowed until your friend has a
chance to return the bow.
Unfortunately, this rule does not account for
the possibility that two friends might bow to
each other at the same time.
----public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s has bowed back to
me!%n“, this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse = new Friend("Alphonse");
final Friend gaston = new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
Java Programming
39
Wait, notifyAll, and notify

The wait() method


The wait() method allows a
thread that is executing a
synchronized method or
statement block on that object
to release the lock and wait for
a notification from another
thread.
The notify() method

Standard Pattern of Wait
synchronized void
doWhenCondition() {
while(!condition) wait();
… Do what must be done when
the condition is true…
}
 Notification
synchronized void
changeCondition() {
… change some value used in a
condition test….
notifyAll(); // or notify()
}

The notify() method allows a
thread that is executing a
synchronized method or
statement block to notify
another thread that is waiting
for a lock on this object.
Java Programming
40
Wait, notifyAll, and notify
Class PrintQueue {
private SinglLinkQueue<PrintJob> queue = new
SingleLinkQueue<PrintJob>();
public synchronized void add(PrintJob j) {
queue.add(j);
notifyAll(); // Tell waiters: print job added
}
public synchronized PrintJob remove() throws InterruptedException {
while (queue.size() == 0)
wait(); // Wait for a print job
return queue.remove();
}
}
Java Programming
41
Producer & Consumer Example
Consumers
Producers
Java Programming
42
Producer & Consumer Example
class Producer extends Thread {
Queue queue;
Producer(Queue queue) {
this.queue = queue;
}
}
public void run() {
int i = 0;
while(true) {
queue.add(i++);
}
}
class Consumer extends Thread {
String str;
Queue queue;
Consumer(String str, Queue queue) {
this.str = str;
this.queue = queue;
}
public void run() {
while(true) {
System.out.println(str + ": " + queue.remove());
}
}
}
class Queue {
private final static int SIZE = 10;
int array[] = new int[SIZE];
int r = 0;
int w = 0;
int count = 0;
synchronized void add(int i) {
while(count == SIZE) {
try {
wait();
}
catch(InterruptedException ie) {
ie.printStackTrace();
System.exit(0);
}
}
array[w++] = i;
if (w >= SIZE)
w = 0;
++count;
notifyAll();
}
Java Programming
43
Producer & Consumer Example
synchronized int remove() {
while(count == 0) {
try {
wait();
}
catch(InterruptedException ie) {
ie.printStackTrace();
System.exit(0);
}
}
int element = array[r++];
if (r >= SIZE)
r = 0;
--count;
notifyAll();
return element;
}
}
class ProducerConsumers {
public static void main(String args[]) {
Queue queue = new Queue();
new Producer(queue).start();
new Consumer("ConsumerA", queue).start();
new Consumer("ConsumerB", queue).start();
new Consumer("ConsumerC", queue).start();
}
}
Java Programming
44
Thread Scheduling

Ending Thread Execution
 The run method returns
normally
 public static void
sleep(long millis)
 public static void
sleep(long millis, int nanos)
 public static void yield()
Run:
% java Babble false 2 Did DidNot
Result:
Did
Did
DidNot
class Babble extends Thread {
static boolean doYield;
static int howOften;
private String word;
Babble(String whatToSay) {
word = whatToSay;
}
public void run() {
for(int i=0; i<howOften; i++) {
System.out.println(word);
if (doYield)
Thread.yield(); // let other threads run
}
}
public static void main(String[] args) {
doYield = new Boolean(args[0]).booleanValue();
howOften = Integer.parseInt(args[1]);
// create a thread for each world
for (int i=2; i < args.length; i++)
new Babble(args[i]).start();
}
}
DidNot
Java Programming
45