Lecture Note 15

Download Report

Transcript Lecture Note 15

Where did the synchronized
methods go?
• Yes, there still exists the synchronized keyword.
• public synchronized void foo() {}
• public void foo(){
aLock.lock();
// atomic code
aLock.unlock(); }
• The scope of a lock is always “per-method” in a
synchronized method.
• You can define arbitrary locking scope with
ReentrantLock.
1
Concurrency: Double-edged Sword
• Must protect shared resources
– Identify potential race conditions
• What must be protected?
• Who access shared resources?
• When shared resources are accessed/changed?
– Synchronizing threads
• Why not have all methods use locks?
• The highest exec overhead in Java program
– Lock acquisition/release
– Thread synchronization
– Garbage collection
• Need to minimize the use of locking and thread
synchronization
2
Minimizing Threading Errors
• A preventive good practice/habit
– Focus on the immutability of objects
• Immutable objects
– Objects that never change its state.
• Only getter methods; no setter methods.
• No need to worry about race conditions.
– e.g. String (java.lang.String)
• char str[] = {’u', ’m', ’b'};
String str = new String(str);
• String str = “umb”;
– A series of constructors to initialize a string data.
– All other methods never change the content of the initialized
string data.
3
StringTest.java
• Output
– umb
–3
– umb
– uml
– umb
– UMB
– umb
4
String Class
• The initialized string data (“umb”) is maintained
in a private variable in String.
– To prevent external objects from updating it.
• The private variable is also final.
– Once a value is assigned to a final variable, the
value cannot be changed afterward.
• Two ways for value assignment
– private final String data = “uml”;
– Use a constructor.
– To prevent methods from updating the initialized
string data (“umb”).
5
• String is a final class.
– public final class String
extends Object
implements Serializable, Comparable<String>,
CharSequence
– A final class cannot be extended to define
subclasses.
– To prevent sub classes from updating the initialized
string data.
• See StringTest2.java
6
Fragile Immutable Class
• The StrData is immutable itself, but it is fragile.
– It becomes mutable once its subclass defines a
setter method.
– Mutable
• A setter method(s) exists.
• Thread unsafe if no thread synchronization is
implemented.
• Remember ThreadSafeBankAccount.
– public class ThreadSafeBankAccount{
private double balance = 0;
…}
7
You Need to…
• Whenever appropriate, use final and private as
often as possible in threaded programs.
– A small changes can cause race conditions.
– Have your compiler work harder!
• Clearly state immutability in program
comments, API documents, design documents,
etc.
– Use {frozen} in UML class diagrams
8
Other Immutable Classes
• Wrapper classes for primitive types
– java.lang.Boolean for boolean
– java.lang.Byte for byte
– java.lang.Character for char
– java.lang.Double for double
– java.lang.Float for floar
– java.lang.Integer for int
– java.lang.Long for long
– java.lang.Short for short
– …etc.
9
Common Pitfalls
• Read Mutable.java and Mutable2.java
• Mutable and Mutable2 are mutable
– although they have no setter methods.
10
• Note that a variable contains a pointer
(reference) to an object
– NOT the object itself.
– When typed as primitive type, a variable contains a
primitive value itself.
• No pointers (references) to primitive values.
11
Minimizing Performance Loss
• Separate (read and write) locks when you have
reader and writer threads
– Readers do not have to compete for a shared
resource.
• Use an immutable object when you have reader
threads only.
• Use the “volatile” keyword when you have writer
threads only.
• Use thread-specific storage.
12
Performance Implication of
Immutable Objects
• Immutable objects are good for performance as
well as threading error avoidance.
– Unnecessary lock acquisition/release and thread
synchronization.
• However, in practice, most objects have both
getter and setter methods…
• Think of separating your object to mutable and
immutable objects
– if the object is read very often.
13
An Example: String and StringBuffer
• Both represent a String data.
• String
– immutable.
– String’s methods do not use locking.
• StringBuffer
– mutable.
– StringBuffer’s methods use locking to read/write a String
data.
• String is faster to read a String data.
– Note: StringBuffer is faster to create a String data from
multiple String data.
14