10. Example --- Simple Counter public class Counter extends Thead { private int count, inc, delay; public Counter(int init, int inc, int delay) { this.count = init; this.inc = inc; this.delay = delay; } public void run() { try { for (;;) { System.out.print(count + “ “); count += inc; sleep(delay); } } catch (InterruptedException e) {} } public static void main(String[] args) { new Counter(0, 1, 33).start(); new Counter(0, -1, 100).start(); } }
11. Example (Cont.) Output: 0 0 1 2 -1 3 4 5 -2 6 7 8 -3 9 10 -4 11 12 13 -5 14 15 16 -6 17 18 -7 19 20 21 -8 22 23 24 -9 25 26 -10 27 28 -11 29 30 31 -12 32 33 34 -13 35 36 37 -14 38 39 -15 40 41 42 -16 43 44 45 … Q: What will happen if we change the statement “new Counter().start()” to “new Counter().run()” in the main method?
12. Exercise Write a thread class named Talker that prints a hello message, say “Hello, I am Tom!”, continuously, and create two instances as separate threads. public class Talker _______________________ { private String name; public Talker(String name) { this.name = name; } }
13.
14. Methods of Thread Class Method Description start() Enter the Runnable state from the new state *sleep() Enter the Non-runnable state join() Enter the Non-runnable state and wait for another thread to terminate *yield() Release CPU and remain in the Runnable interrupt() Cause InterruptedException isAlive() True if in the alive state isInterrupted() True if interrupted * static method
15. Example Coordinating concurrent jobs public class Job extends Thread { public void run() { // do some meaningful work, e.g., writing multithreaded applets. } public static void main(String[] args) { Job[] jobs = new Job[10]; for (int i = 0; i < jobs.length; i++) { jobs[i] = new Job(); jobs[i].start(); } for (int i = 0; i < jobs.length; i++) { jobs[i].join(); } } } jobs[0] … jobs[9] main
16. Exercise Explain the execution flow of the following program. public class Job extends Thread { public void run() { // do some meaningful work, e.g., writing multithreaded applets. } public static void main(String[] args) { Job[] jobs = new Job[10]; for (int i = 0; i < jobs.length; i++) { jobs[i] = new Job(); jobs[i].start(); jobs[i].join(); } } }
17.
18.
19.
20.
21. Example public class Account { private long balance; public synchronized boolean withdraw(long amount) { if (amount <= balance) { long newBalance = balance – amount; balance = newBalance; return true; } else { return false; } } // other methods and fields }
22. Exercise Make withdraw method synchronized by using the synchronized statement. public class Account { private long balance; public boolean withdraw(long amount) { // WRITE YOUR CODE HERE… if (amount <= balance) { long newBalance = balance – amount; balance = newBalance; return true; } else { return false; } } }
23.
24. Example --- Bounded Queue A first-in, first-out queue with a fixed capacity public class BoundedQueue { protected Object rep[]; // circular array protected int front = 0; // front of the queue protected int back = -1; // back of the queue protected int size; // capacity of the queue protected int count = 0; // num of objects in the queue //@ requires size > 0; public BoundedQueue(int size) { this.size = size; rep = new Object[size]; back = size – 1; } public boolean isEmpty() { return (count == 0); }
25. Bounded Queue (Cont.) public boolean isFull() { return (count == size); } public int getCount() { return count; } public void put(/*@ non_null @*/ Object e) { if (!isFull()) { back = (back + 1) % size; rep[back] = e; count++; } } public Object get() { Object result = null; if (!isEmpty()) { result = rep[front]; front = (front + 1) % size; count--; } return result; } }
26. Making Queue Thread-Safe public class SyncBoundedQueue extends BoundedQueue { public SyncBoundedQueue(int size) { super(size); } public synchronized boolean isEmpty() { return super.isEmpty(); } public synchronized boolean isFull() { return super.isFull(); } public synchronized int getCount() { return super.getCount(); } public synchronized void put(Object e) { super.put(e); } public synchronized Object get() { return super.get(); } }
27. Use of Bounded Queue Typical use in producers and consumers Thread Thief Broker SyncBoundedQueue
28. Producer public class Thief extends Thread { private BoundedQueue queue; private int n; // number of items to steal public Producer(BoundedQueue queue, int n) { this.queue = queue; this.n = n; } public void run() { for (int i = 0; i < n; i++) { queue.put(new Integer(i)); System.out.println(“produced: “ + i); try { sleep((int) (Math.random() * 100)); } catch (InterruptedException e) {} } } }
29. Consumer public class Broker extends Thread { private BoundedQueue queue; private int n; // number of stolen items to sell public Consumer(BoundedQueue queue, int n) { this.queue = queue; this.n = n; } public void run() { for (int i = 0; i < n; i++) { Object obj = queue.get(); System.out.println(“consumed: “ + obj); try { sleep((int) (Math.random() * 400)); } catch (InterruptedException e) {} } } }
30. Sample Main Program The main method of class SyncBoundedQueue public static void main(String[] args) { SyncBoundedQueue queue = new SyncBoundedQueue(5); new Thief(queue, 15).start(); // produce 15 items new Broker(queue, 10).start(); // consume 10 items } Output Some of the items might be lost, as the producer produces items faster than the consumer consumes them.
31.
32. Thread Methods of Class Object Method Description wait() Temporarily blocked and placed in the wait queue of the receiving object. notify() Awaken one of the threads in the wait queue associated with the receiving object and remove it from the queue. notifyAll() Same as notify() except that all threads in the wait queue are awakened.
33. Bounded Queue with Guarded Suspension public class BoundedQueueWithGuard extends BoundedQueue { public Producer(int size) { super(size); } public synchronized boolean isEmpty() { return super.isEmpty(); } public synchronized boolean isFull() { return super.isFull(); } public synchronized int getCount() { return super.getCount(); } <<put, get, and main method>> }
34. Put Method public synchronized void put(Object obj) { try { while (isFull()) { wait(); } } catch (InterruptedException e) {} super.put(e); notify(); }
35. Exercise --- Get Method Write the get method with guarded suspension. public synchronized Object get() { // WRITE YOUR CODE HERE. }
36. Smart Thief and Broker public static void main(String args[]) { BoundedQueueWithGuard queue = new BoundedQueueWithGuard(5); new Thief(queue, 15).start(); // produce 15 items. new Broker(queue, 15).start(); // consume 15 times } Output: No lost items!
Notas del editor
Squential : tuần tự Concurrently : đồng thời, kiêm
Reactive : tác động trở lại, ảnh hưởng trở lại Suitable : phù hợp, thích hợp
synchronized public Object get() { try { while (isEmpty()) { wait(); } } catch (InterruptedException e) {} Object result = super.get(); notify(); return result; }
public synchronized Object get() { try { while (isEmpty()) { wait(); } } catch (InterruptedException e) {} Object result = super.get(); notify(); return result; }