티스토리 뷰
synchronized 이해
하나의 객체에 여러 요청이 동시에 들어오면 원하는 처리를 하지 못하고 이상한 결과가 나올 수 있습니다.
- 그래서 synchronized를 사용하여 동기화를 하는 것입니다.
- 이 식별자를 사용하면 "천천히 하나씩 들어오세요."라고 해당 메소드나 블럭에서 제어하게 됩니다.
*코드 예제
public synchronized void sampleMethod() {
...
}
private Object obj = new Object();
public void sampleBlock() {
synchronized(obj) {
...
}
}
- 위 처럼 간단히 synchronized라는 식별자만 사용하면 동기화할 수 있습니다.
언제 동기화를 사용해야 할까 ?
- 하나의 객체를 여러 스레드에서 동시에 사용할 경우
- static으로 선언한 객체를 여러 스레드에서 동시에 사용할 경우
동일 객체 접근시
public class Contribution {
private int amount = 0;
public synchronized void donate() {
amount++;
}
public int getTotal() {
return amount;
}
}
public class Contribution extends Thread {
private Contribution myContribution;
private String myName;
public Contributor(Contribution contrubution, String name) {
myContribution = contribution;
myName = name;
}
public void run() {
for (int loop = 0; loop < 1000; ++loop)
myContribution.donate();
System.out.format("%s total = %d\n", myName, myContribution.getTotal());
}
}
public class ContributeTest {
public static void main(String args[]) {
Contributor[] crs = new Contributor[10];
Contribution group = new Contribution();
// 기부자와 기부 단체 초기화
for (int loop = 0; loop < 10; ++loop)
crs[loop] = new Contributor(group, " Contributor" + loop);
// 기부 실행
for (int loop = 0; loop < 10; ++loop)
crs[loop].start();
}
}
static 사용시
public class Contribution {
private static int amount = 0;
public static synchronized void donate() {
amount++;
}
public int getTotal() {
return amount;
}
}
public class Contribution extends Thread {
private Contribution myContribution;
private String myName;
public Contributor(Contribution contrubution, String name) {
myContribution = contribution;
myName = name;
}
public void run() {
for (int loop = 0; loop < 1000; ++loop)
myContribution.donate();
System.out.format("%s total = %d\n", myName, myContribution.getTotal());
}
}
public class ContributeTest {
public static void main(String args[]) {
Contributor[] crs = new Contributor[10];
// 기부자와 기부 단체 초기화
for (int loop = 0; loop < 10; ++loop) {
Contribution group = new Contribution();
crs[loop] = new Contributor(group, " Contributor" + loop);
}
// 기부 실행
for (int loop = 0; loop < 10; ++loop)
crs[loop].start();
}
}
- amount를 static으로 선언하면 객체의 변수가 아닌 클래스의 변수가 됩니다.
- 따라서, 각 단체에 따로 기부하는 것은 구현이 불가능합니다.
- synchronized는 각각의 객체에 대한 동기화를 하는 것이기 때문에, synchronized만 사용하면 amount에 대한 동기화는 되지 않습니다.
- 그래서 static synchronized로 구현했지만, 항상 변하는 값(amount)에 대해서 static으로 선언하는 것은 굉장히 위험하다는 것을 알아두시면 좋겠습니다.
'Language > Java' 카테고리의 다른 글
Reflection class (0) | 2018.06.01 |
---|---|
Thread Class & Runnable Interface (0) | 2018.06.01 |
Process & Thread (0) | 2018.06.01 |
IO (0) | 2018.06.01 |
Static (0) | 2018.06.01 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- cors
- synchronized
- Java
- SPOF
- 404
- Token
- NoSQL
- stateful
- JWT
- auth
- Groovy
- Cross Origin
- output
- iinput
- thread
- URI
- MongoDB
- Runnable
- stateless
- class
- ehcache
- HTTP
- redis
- ngrinder
- https
- 대규모
- Spring Boot
- cross
- script
- web
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함