동기화 된 블록을 이해하려고합니다. 여기서는 하나의 제작자 스레드와 2 개의 소비자 스레드를 구현했습니다.자바 멀티 스레딩 : 느린 프로듀서 및 고속 사용자
LinkedList가 비어있어 스레드에서 예외가 계속 발생합니다.
package com.Main;
import com.qed.Consumer;
import com.qed.Producer;
import com.qed.Store;
public class Main {
public static void main(String[] args) throws InterruptedException {
Store st = new Store();
Thread populate = new Thread(new Producer(st));
Thread con1 = new Thread(new Consumer(st));
Thread con2 = new Thread(new Consumer(st));
con1.setName("A");
con2.setName("B");
populate.start();
con1.start();
con2.start();
populate.join();
con1.join();
con2.join();
if(populate.isAlive()){
con1.interrupt();
con2.interrupt();
}
}
}
package com.qed;
import java.util.LinkedList;
public class Store {
private LinkedList<Integer> qu = new LinkedList<Integer>();
private final Object lock = new Object();
public void add(int data){
try{
while(qu.size() ==10){
Thread.sleep(1);
}
qu.add(data);
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
public int remove(){
int data=0;
try{
synchronized(lock){
while(qu.size() == 0){
Thread.sleep(1);
}
data = qu.removeFirst();
}
}catch(InterruptedException ie){
ie.printStackTrace();
}
return data;
}
}
package com.qed;
public class Consumer implements Runnable{
private Store st;
public Consumer(Store st){
this.st=st;
}
public void run(){
while(true){
System.out.println(Thread.currentThread().getName() + ". " +st.remove());
}
}
}
package com.qed;
public class Producer implements Runnable{
private Store st;
private final int runs = 5000;
public Producer(Store st){
this.st = st;
}
public void run(){
int data = 0;
int curRun =0;
while(++curRun < runs){
st.add(data+=200);
}
System.out.println("DONE.");
}
}
스택 추적 :
Exception in thread "B" Exception in thread "A"
java.util.NoSuchElementException
at java.util.LinkedList.removeFirst(Unknown Source)
at com.qed.Store.remove(Store.java:46)
at com.qed.Consumer.run(Consumer.java:20)
at java.lang.Thread.run(Unknown Source)
java.util.NoSuchElementException
at java.util.LinkedList.removeFirst(Unknown Source)
at com.qed.Store.remove(Store.java:46)
at com.qed.Consumer.run(Consumer.java:20)
at java.lang.Thread.run(Unknown Source)
'add()'에서 동기화하지 않으면 정의되지 않은 동작입니다. – 1000ml