문제없이 공유객체를 사용하는 방법.
-
필드 사용 시 synchronized를 붙인다.(동시 호출되지않고 한 쓰레드가 끝날때까지 다른 sync는 실행되지 않는다.)
-
필드자체가 동시에 사용될 수 없도록 만든다.(쓰레드 safe 하게 만든다.)
*쓰레드를 동시에 실행하면 누가 먼저 실행될지 알 수 없기 때문에 wait, notify같은걸 사용한다. monitoring lock - 참조바람
예>
Runable 인터페이스를 상속받아 쓰레드 구성
public class BoxThread implements Runnable{
private Box box;
private int num;
public BoxThread(Box box, int num){
this.box = box;
this.num = num;
}
@Override
public void run() {
if(num == 1)
box.methodA();
else if(num == 2)
box.methodB();
else if(num == 3)
box.methodC();
}
}
Synchronized block
public class Box {
private List<String> list;
public Box(){
list = new ArrayList<>();
}
public void methodA(){
synchronized (list) {
for (int i = 1; i < 1000; i++) {
list.add(i + "");
}
}
} // methodA
public void methodB(){
synchronized (list) {
for (int i = 1; i < 1000; i++) {
try {
list.remove(0);
} catch (Exception ignore) {
}
}
}
} // methodA
public void methodC(){
synchronized (list) {
for (int x = 0; x < 1000; x++) {
int size = list.size();
for (int i = 0; i < size; i++) {
System.out.println(list.get(i));
}
}
}
} // methodA
}
public class BoxMain {
public static void main(String[] args){
Box box = new Box();
Thread t1 = new Thread(new BoxThread(box, 1));
Thread t2 = new Thread(new BoxThread(box, 2));
Thread t3 = new Thread(new BoxThread(box, 3));
t1.start();
t2.start();
t3.start();
System.out.println("end!");
}
}
~~~