Java Synchronization ~

27
2000 운운운운 운운운운운 운운운운운운 운운운 7.1 Java Synchronization ~ Synchronized, wait(), notify() statements Multiple Notifications Block Synchronization Java Semaphores Java Monitors

description

Java Synchronization ~. Synchronized, wait(), notify() statements Multiple Notifications Block Synchronization Java Semaphores Java Monitors. Java Synchronization ~. Thread safe: 여러 thread 에 의해 동시에 접근되어도 데이터의 일관성( data consistency) 을 보장할 수 있을 때 Synchronized Statement - PowerPoint PPT Presentation

Transcript of Java Synchronization ~

Page 1: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.1

Java Synchronization ~

• Synchronized, wait(), notify() statements

• Multiple Notifications

• Block Synchronization

• Java Semaphores

• Java Monitors

Page 2: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.2

Java Synchronization ~

• Thread safe: 여러 thread 에 의해 동시에 접근되어도 데이터의 일관성 (data consistency) 을 보장할 수 있을 때

• Synchronized Statement

» Every object has a lock associated with it.

» Calling a synchronized method requires “owning” the lock.

» If a calling thread does not own the lock (another thread already owns it), the calling thread is placed in the wait set for the object’s lock.

» The lock is released when a thread exits the synchronized method.

Page 3: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.3

Java Synchronization ~

• Entry Set

Page 4: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.4

Java Synchronization ~

<synchronized 와 yield() 이용한 Bounded Buffer> : deadlock 가능 ( 어떻게 ? 왜?)

• Synchronized enter() Method

public synchronized void enter(Object item) {

while (count == BUFFER_SIZE)

Thread.yield();

++count;

buffer[in] = item;

in = (in + 1) % BUFFER_SIZE;

}

• Synchronized remove() Method

public synchronized Object remove() {

Object item;

while (count == 0)

Thread.yield();

--count;

item = buffer[out];

out = (out + 1) % BUFFER_SIZE;

return item;

}

• The wait() Method

When a thread calls wait(), the following occurs:

- the thread releases the object lock.

- thread state is set to blocked.

- thread is placed in the wait set.

Page 5: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.5

Java Synchronization ~

• Entry and Waits Set

Page 6: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.6

Java Synchronization ~

• Notify Method

When a thread calls notify(), the following occurs:

- selects an arbitrary thread T from the wait set.

- moves T to the entry set.

- sets T to Runnable.

T can now compete for the object’s lock again.

Page 7: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.7

Java Synchronization ~

<synchronized, wait(), notify() 이용한 Bounded Buffer>

• enter() with wait/notify Methods

public synchronized void enter(Object item) {

while (count == BUFFER_SIZE)

try {

wait();

}

catch (InterruptedException e) { }

}

++count;

buffer[in] = item;

in = (in + 1) % BUFFER_SIZE;

notify();

}

• remove() with wait/notify Methods

public synchronized Object remove() {

Object item;

while (count == 0)

try {

wait();

}

catch (InterruptedException e) { }

--count;

item = buffer[out];

out = (out + 1) % BUFFER_SIZE;

notify();

return item;

}

Page 8: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.8

Java Synchronization ~

• Bounded Buffer 완전한 해법public class BoundedBufferServer

{

public static void main(String args[]) {

BoundedBuffer server = new BoundedBuffer();

// now create the producer and consumer threads

Producer producerThread = new Producer(server);

Consumer consumerThread = new Consumer(server);

producerThread.start();

consumerThread.start();

}

}

Page 9: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.9

Java Synchronization ~

import java.util.*;public class Producer extends Thread{ public Producer(BoundedBuffer b) { buffer = b; } public void run() { Date message; while (true) { BoundedBuffer.napping(); // produce an item & enter it into the

buffer message = new Date(); System.out.println("Producer

produced " + message); buffer.enter(message); } } private BoundedBuffer buffer;}

import java.util.*;public class Consumer extends Thread{ public Consumer(BoundedBuffer b) { buffer = b; } public void run() { Date message; while (true) {

BoundedBuffer.napping(); // consume an item from the buffer System.out.println("Consumer wants to

consume."); message = (Date)buffer.remove(); } } private BoundedBuffer buffer;}

Page 10: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.10

Java Synchronization ~

public class BoundedBuffer { public BoundedBuffer() { // buffer is initially empty count = 0; in = 0; out = 0; buffer = new Object[BUFFER_SIZE]; } // producer and consumer will call this to nap public static void napping() { int sleepTime = (int) (NAP_TIME * Math.random() ); try { Thread.sleep(sleepTime*1000); } catch(InterruptedException e) { } } public synchronized void enter(Object item) {…}; public synchronized Object remove() {…}; public static final int NAP_TIME = 5; private static final int BUFFER_SIZE = 5; private int count; // number of items in the buffer private int in; // points to the next free position in the buffer private int out; // points to the next full position in the buffer private Object[] buffer;}

Page 11: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.11

Java Synchronization ~

public synchronized void enter(Object item) {

while (count == BUFFER_SIZE) { try { wait(); } catch (InterruptedException e) { } } // add an item to the buffer ++count; buffer[in] = item; in = (in + 1) % BUFFER_SIZE;

if (count == BUFFER_SIZE) System.out.println("Producer Entered “ + item + " Buffer FULL");

else System.out.println("Producer Entered “ + item + " Buffer Size = " + count);

notify(); }

public synchronized Object remove() { Object item; while (count == 0) { try { wait(); } catch (InterruptedException e) { } } // remove an item from the buffer --count; item = buffer[out]; out = (out + 1) % BUFFER_SIZE;

if (count == 0)System.out.println("Consumer

Consumed " + item + " Buffer EMPTY");else

System.out.println("Consumer Consumed " + item + " Buffer Size = " + count);

notify(); return item; }

Page 12: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.12

Java Synchronization ~

<Readers-Writers>

• Database class with Java Synchronization

public class Database {

public Database() {

readerCount = 0;

dbReading = false;

dbWriting = false;

}

public synchronized int startRead() { /* see next slides */ }

public synchronized int endRead() { /* see next slides */ }

public synchronized void startWrite() { /* see next slides */ }

public synchronized void endWrite() { /* see next slides */ }

private int readerCount;

private boolean dbReading;

private boolean dbWriting;

}

Page 13: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.13

Java Synchronization ~

• Reader Methodspublic synchronized int startRead() {

while (dbWriting == true) {try {

wait();}catch

(InterruptedException e) { } }

++readerCount;if (readerCount == 1)

dbReading = true;return readerCount;

}

public synchronized int endRead() { --readerCount if (readerCount == 0) dbReading = false; notifyAll(); return readerCount; }

• Writer Method

public synchronized void startWrite() {

while (dbReading == true || dbWriting == true)

try {

wait();

}

catch (InterruptedException e) { }

dbWriting = true;

}

public synchronized void endWrite() {

dbWriting = false;

notifyAll();

}

Page 14: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.14

Java Synchronization

public class Reader extends Thread{ public Reader(int r, Database db) { readerNum = r; server = db; } public void run() { int c; while (true) { System.out.println("reader " + readerNum + " is sleeping."); Database.napping();

System.out.println("reader " + readerNum + " wants to read."); c = server.startRead(readerNum); // you have access to read from the database System.out.println("reader " + readerNum + " is reading. Count = " + c); Database.napping(); c = server.endRead(readerNum); System.out.println("reader " + readerNum + " is done reading. Count = "

+ c); } } private Database server; private int readerNum;}

Page 15: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.15

Java Synchronization

public class Writer extends Thread{ public Writer(int w, Database db) { writerNum = w; server = db; } public void run() { while (true) { System.out.println("writer " + writerNum + " is sleeping."); Database.napping(); System.out.println("writer " + writerNum + " wants to write."); server.startWrite(writerNum); // you have access to write to the database System.out.println("writer " + writerNum + " is writing."); Database.napping();

server.endWrite(writerNum); System.out.println("writer " + writerNum + " is done writing."); } } private Database server; private int writerNum;}

Page 16: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.16

Java Synchronization

public class ReaderWriterServer { public static void main(String args[]) { Database server = new Database(); Reader[] readerArray = new Reader[NUM_OF_READERS]; Writer[] writerArray = new Writer[NUM_OF_WRITERS]; for (int i = 0; i < NUM_OF_READERS; i++) { readerArray[i] = new Reader(i, server); readerArray[i].start(); } for (int i = 0; i < NUM_OF_WRITERS; i++) { writerArray[i] = new Writer(i, server); writerArray[i].start(); } } private static final int NUM_OF_READERS = 3; private static final int NUM_OF_WRITERS = 2;}

Page 17: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.17

Multiple Notifications

• notify() selects an arbitrary thread from the wait set. *This may not be the thread that you want to be selected.

• Java does not allow you to specify the thread to be selected.

• notifyAll() removes ALL threads from the wait set and places them in the entry set. This allows the threads to decide among themselves who should proceed next.

• notifyAll() is a conservative strategy that works best when multiple threads may be in the wait set.

Page 18: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.18

DoWork() ~

public class DoWork {// pnum is the number of the thread that wishes to do some workpublic synchronized void DoWork(int pnum) {

while (turn != pnum) {try {

wait();}catch (InterruptedException e) {}

}// do some work for awhileSystem.out.println("Worker " + pnum + " will do some work");try {

Thread.sleep( (int) (Math.random() * 3000) ); } catch (InterruptedException e) { }

// ok, we're finished. Now indicate to the next waiting// thread that it is their turn to do some work.System.out.println("Worker " + pnum + " is done working");if (turn < 5)

++turn;else

turn = 1;// change this to notifyAll() to see it run correctly!notify();

}private int turn = 1;

}

Page 19: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.19

DoWork() ~

public class Worker extends Thread{ public Worker(DoWork p, String n, int i) {

pile = p;name = n;num = i;

} public void run() { while (true) { Runner.slacking();

pile.DoWork(num); } } private DoWork pile; private String name; private int num;}public class Runner{ public static void slacking() { try { Thread.sleep( (int) (Math.random() * 3000) ); } catch (InterruptedException e) { } }}

public class TestIt { public static void main(String args[]) { DoWork pile = new DoWork(); Worker[] bees = new Worker[5]; for (int i = 1; i <= 5; i++) bees[i-1] = new Worker(pile,

"Worker “ + (new Integer(i)).toString(),

i); for (int i = 1; i <= 5; i++) bees[i-1].start(); }}

Page 20: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.20

Block Synchronization

• Blocks of code – rather than entire methods – may be declared as synchronized.

• This yields a lock scope that is typically smaller than a synchronized method.

• synchronized block 안에서 wait() 와 notify() 사용 가능

Object mutexLock = new Object();

. . .

public void someMethod() {

// non-critical section

synchronized(mutexLock) {

// critical section

}

// non-critical section

}

Page 21: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.21

Java Semaphores ~

• Java does not provide a semaphore, but a basic semaphore can be constructed using Java synchronization mechanism.

public class Semaphore { public Semaphore() {

value = 0; }

public Semaphore(int v) { value = v;

} public synchronized void P() { while (value <= 0) { try { wait(); } catch (InterruptedException e) { } } value --; } public synchronized void V() { ++value; notify(); } private int value;}

Page 22: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.22

Linux 에서 Wait Queue 와 Semaphore

• Linux 의 세마포어 원자적 연산 구현» P(S) 에서 process status 를 TASK_UNINTERRUPTIBLE 로

uninterruptible 하게 만들고 대기큐에 들어가고 CPU 스케줄러 호출하여 제어를 넘김

» V(S) 에서 TASK_RUNNING 으로 재활성화 됨» (Linux Kernel Internals, 2nd Ed., p34~36 참조 )

struct wait_queue() {Int task_struct *task;struct wait_queue *next;

};

struct semaphore() {Int count;struct wait_queue *wait;

};void add_wait_queue(struct wait_queue ** queue, struct wait_queue *entry);void remove_wait_queue(struct wait_queue ** queue, struct wait_queue *entry);

Page 23: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.23

Linux 에서 Wait Queue 와 Semaphore

void down(structure semaphore *sem){ while(sem->count <= 0)

sleep_on(sem->wait);sem->count--;

}void up(structure semaphore *sem){

sem->count++;wake_up(&sem->wait);

}

void sleep_on(struct wait_queue **queue){ struct wait_queue entry = {current, NULL}; current->state=TASK_UNINTERRUPTIBLE; add_wait_queue(queue, &entry); schedule(); remove_wait_queue(queue, *entry);}void wake_up(struct wait_queue **queue){ struct wait_queue *p = *queue; do { p->task->state = TASK_RUNNING; p = p->next; } while(p != *queue);}

Page 24: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.24

Java Semaphores

• Java 의 동기화 규칙 (synchronization rules)1. 하나의 thread 는 어떤 객체의 lock 을 가진 상태에서 그 객체에 대한 다른

synchronized method ( 또는 block) 에 진입할 수 있다 .2. 하나의 thread 는 다른 객체에 대한 synchronized method 호출을 내포

(nest) 할 수 있다 . 즉 , 하나의 thread 는 동시에 여러개의 다른 객체에 대한 lock 을 소유할 수 있다 .

3. synchronized 로 선언되어 있지 않은 어떤 객체의 method 는 그 객체에 대하여 다른 synchronized method 가 실행 중일 지라도 lock 의 소유에 상관없이 그 객체에 대한 method 를 호출할 수 있다 .

4. 만일 어떤 객체에 대한 wait set 가 비어있다면 notify() 나 notifyAll() 은 아무 영향을 주지 않는다 .

• Java Monitor» Java synchronization 의 lock 은 모니터처럼 동작» 모든 Java 객체는 연관된 monitor 를 가짐» Java 는 이름 없는 하나의 조건변수 (a unnamed condition variable) 를

가지는 모니터• condition.wait : wait()• condition.signal: notify(), notifyAll()• notify(), notyfyAll() 로 깨어난 thread 는 스스로 조건이 맞는지 조사

» Java monitor 는 signal-and-continue 접근

Page 25: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.25

Solaris 2 에서의 동기화 (Synchronization in Solaris 2)

1. 적응성 (adaptive) mutexes : 짧은 임계구역에i) multiprocessor system 에서

• 처음에는 표준 세마포어처럼 동작 (spinlock) 하다 사용하려는 데이터가 lock 되었을 때

① lock 한 프로세스가 running thread 이면 • 그대로 spinlock 하다가 진행

② lock 한 프로세스가 running thread 아니면 (spinlock 시간이 길어짐 )• sleeping thread 로 처리 : block 되어 sleep 했다가 wakeup 됨 ( 바쁜

대기 없는 세마포어 처럼 )ii) uniprocessor system 에서

• 항상 sleeping thread 로 처리» 다른 thread 가 lock test 하는 순간 이미 CPU 는 다른 thread 처리

중이므로2. 조건 변수 (Condition variable) : 긴 임계구역에

» lock 되었으면 thread 는 wait and sleeps» lock 을 푸는 스레드가 signal

3. 판독자 - 기록자 잠금 (readers-writers locks) : 긴 임계구역에 » 대부분의 경우 read-only 인 data 보호» semaphore 보다 유리 (multiple reads 가능하므로 )

Page 26: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.26

Windows NT Synchronization

• Windows NT Provides:

» mutex( 뮤텍스 )• 스레드가 공유 데이터 접근 위해 사용

» critical sections( 임계구역 )• 같은 프로세스의 스레드 사이의 동기화 를 제공하는데 사용

» semaphores( 세마포어 )

» event objects( 사건 객체 )• 조건 변수와 유사한 동기화 객체• 원하는 조건이 일어났을 때 하나의 대기 스레드에게 통보

(notify)

Page 27: Java Synchronization  ~

2000 운영체제 인천대학교 컴퓨터공학과 성미영 7.27

수업

류시화 엮은 잠언시집 : 지금 알고 있는 걸 그때도 알았더라면 중에서

그때 예수께서 제자들을 산으로 데리고 올라가

곁에 둘러앉히시고 이렇게 가르치셨다 .

마음이 가난한 사람은 행복하다 . 하늘나라가 그들의 것이다 .

온유한 사람은 행복하다 .

슬퍼하는 사람은 행복하다 .

자비를 베푸는 사람은 행복하다 .

박해받는 사람은 행복하다 .

고통받는 사람은 행복하다 .

하늘나라에서의 보상이 크니 기뻐하고 즐거워하라 .

그러자 시몬 베드로가 말했다 .

“ 그 말씀을 글로 적어 놓으리까 ?”

그리고 안드레아가 말했다 .

“ 그 말씀을 잘 새겨 둬야 할까요 ?”

그러자 야고보가 말했다 .

“ 그걸 갖고 우리끼리 시험을 쳐볼까요 ?

그러자 빌립보가 말했다 .

“ 우리가 그 뜻을 잘 모를 경우에는 어떻게 할까요 ?”

그리고 바돌로메가 말했다 .

“ 우리가 이 말씀을 다른 사람들에게 전해 줘야 할까요 ?”

그러자 요한이 말했다 .

“ 다른 제자들한테는 이런 걸 알려줄 필요가 있을까요 ?”

그러자 마태오가 말했다 .

“ 우리는 여기서 언제 떠날 건가요 ?”

그리고 유다가 말했다 .

“ 그 말씀이 실생활과는 어떤 관계가 있는 걸까요 ?”

그리고 그 자리에 참석했던 바리새인 하나는

예수에게 수업 계획서를 보여 줄 것을 요청하면서

그 가르침의 최종적인 목표가 무엇이냐고 물었다 .

그러자 예수께서는 우셨다 .

작자 미상

M. 스콧 펙 제공