9
Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP://WWW-SCF.USC.EDU/ ~CSCI201 USC CSCI 201L

Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Embed Size (px)

Citation preview

Page 1: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

LocksCSCI 201L

Jeffrey Miller, Ph.D.

HTTP://WWW-SCF.USC.EDU/~CSCI201

USC CSCI 201L

Page 2: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Outline

USC CSCI 201L 2/9

▪ Locks› Lock Conditions

Page 3: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

synchronized Keyword

▪ The synchronized keyword puts a restriction on a method that only one thread can be inside at a time› This is accomplished using a monitor› No other thread will be able to enter that method if another

thread is currently executing inside of it, regardless of whether it is in the CPU currently or not

USC CSCI 201L 3/9Locks

Page 4: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Explicitly Acquiring Locks

▪ A synchronized method or block of code implicitly acquires a lock on the instance before executing

▪ Java gives us the ability to explicitly acquire locks using the java.util.concurrent.locks.Lock interface and java.util.concurrent.locks.ReentrantLock class

USC CSCI 201L 4/9Locks

Page 5: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

synchronized Keyword Example1 import java.util.concurrent.ExecutorService;2 import java.util.concurrent.Executors;34 public class AddAPenny implements Runnable {5 private static PiggyBank piggy = new PiggyBank();67 public void run() {8 piggy.deposit(1);9 }1011 public static void main(String [] args) {12 ExecutorService executor = Executors.newCachedThreadPool();13 for (int i=0; i < 100; i++) {14 executor.execute(new AddAPenny());15 }16 executor.shutdown();17 // wait until all tasks are finished18 while(!executor.isTerminated()) { }1920 System.out.println("Balance = " + piggy.getBalance());21 }22 }2324 class PiggyBank {25 private int balance = 0;26 public int getBalance() {27 return balance;28 }29 public synchronized void deposit(int amount) {30 int newBalance = balance + amount;31 Thread.yield();32 balance = newBalance;33 }34 } USC CSCI 201L 5/9Locks

4 Executions

Page 6: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Explicitly Acquiring Locks Example1 import java.util.concurrent.ExecutorService;2 import java.util.concurrent.Executors;3 import java.util.concurrent.locks.Lock;4 import java.util.concurrent.locks.ReentrantLock;56 public class AddAPenny implements Runnable {7 private static PiggyBank piggy = new PiggyBank();89 public void run() {10 piggy.deposit(1);11 }1213 public static void main(String [] args) {14 ExecutorService executor = Executors.newCachedThreadPool();15 for (int i=0; i < 100; i++) {16 executor.execute(new AddAPenny());17 }18 executor.shutdown();19 // wait until all tasks are finished20 while(!executor.isTerminated()) { }2122 System.out.println("Balance = " + piggy.getBalance());23 }24 }2526 class PiggyBank {27 private int balance = 0;28 private Lock lock = new ReentrantLock();29 public int getBalance() {30 return balance;31 }32 public void deposit(int amount) {33 lock.lock();34 try {35 int newBalance = balance + amount;36 Thread.yield();37 balance = newBalance;38 } finally {39 lock.unlock();40 }41 }42 }

USC CSCI 201L 6/9Locks

4 Executions

Page 7: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Thread Conditions

▪ Threads are able to communicate with each other based on specific conditions

▪ Threads can perform the following actions using the java.util.concurrent.Condition interface› await()

• Wait for the condition to be signaled

› signal()• Wake up one thread waiting on the condition

› signalAll()• Wake up all of the threads waiting on the condition

▪ A Condition is created from a Lock object by calling the newCondition() method

USC CSCI 201L 7/9Locks – Lock Conditions

Page 8: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Thread Conditions Example1 import java.util.concurrent.ExecutorService;2 import java.util.concurrent.Executors;3 import java.util.concurrent.locks.Condition;4 import java.util.concurrent.locks.Lock;5 import java.util.concurrent.locks.ReentrantLock;67 public class AddAndRemoveAPenny implements Runnable {8 private static PiggyBank piggy = new PiggyBank();9 private boolean isWithdrawal;1011 public void run() {12 if (isWithdrawal) {13 piggy.deposit((int)(Math.random() * 9 + 1));14 }15 else {16 piggy.withdraw((int)(Math.random() * 9 + 1));17 }18 }1920 public static void main(String [] args) {21 ExecutorService executor = Executors.newCachedThreadPool();22 for (int i=0; i < 100; i++) {23 AddAndRemoveAPenny penny = new AddAndRemoveAPenny();24 if (i < 50) { // exactly 50 threads will withdraw25 penny.isWithdrawal = false;26 }27 else { // and exactly 50 threads will deposit28 penny.isWithdrawal = true;29 }30 executor.execute(penny);31 }32 executor.shutdown();33 // wait until all tasks are finished34 while(!executor.isTerminated()) { }3536 System.out.println("Balance = " + piggy.getBalance());37 }38 }

USC CSCI 201L 8/9Locks – Lock Conditions

39 class PiggyBank {40 private int balance = 0;41 private Lock lock = new ReentrantLock();42 private Condition depositMade = lock.newCondition();43 public int getBalance() {44 return balance;45 }46 public void withdraw(int amount) {47 lock.lock();48 try {49 while (balance < amount) {50 System.out.print("Waiting for deposit...”);51 System.out.print(“ to withdraw $" + amount);52 System.out.println(" from balance of $" + balance);53 depositMade.await();54 }55 balance -= amount;56 System.out.print("$" + amount + " withdrawn,”);57 System.out.println(“ leaving balance of $" + balance);58 } catch (InterruptedException ie) {59 System.out.println("IE: " + ie.getMessage());60 } finally {61 lock.unlock();62 }63 }64 public void deposit(int amount) {65 lock.lock(); // acquires lock66 try {67 balance += amount;68 System.out.print("$" + amount + " deposited,”);69 System.out.println(“ making balance of $" + balance);70 depositMade.signalAll();71 } finally {72 lock.unlock(); // release the lock73 }74 }75 }

Page 9: Locks CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L

Thread Conditions Issues

▪ Once a thread invokes await() on a condition, the thread will move to the waiting state until it is signaled› If signal() or signalAll() is never called on the condition, the

thread will wait forever› In the previous example, some executions of the program

never terminate if a withdrawal was not able to be made based on the balance after all the deposits were made

▪ You must first obtain the lock on the object before you are able to invoke a method on its Condition› When a thread calls await(), it will release its lock

• It will not be able to start executing again, even after it is signaled, if it is not able to obtain the lock again

USC CSCI 201L 9/9Locks – Lock Conditions