2012년 7월 23일 월요일
java thread runnable synchronized volatile
현업에 있다보니 쓰레드 쓸 일이 없어서 잊고 있다가 한번 제대로 정리 해 보려고
디노보 엣지(내 키보드 이름)를 잡았다
쓰레드를 예제로 배워보자. 쓰레드는 이런 것...
-----------------------------------------------------
public class HelloWorld extends Thread {
private static final double a = 0;
public void run() {
while (true) {
System.out.println("Current Count = " + a);
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
HelloWorld t1 = new HelloWorld();
try {
t1.start();
} catch (Exception e) {
// TODO: handle exception
}
}
}
---------------------------------------------------------------
걍 메인문에다가 while(true)하고 적는 거랑 뭐가 다를까...
--------------------------------------------------------------
public class HelloWorld extends Thread {
private static final double a = 0;
public void run() {
while (true) {
System.out.println("Current Count = " + a);
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
HelloWorld t1 = new HelloWorld();
HelloWorld t2 = new HelloWorld();
try {
t1.start();
t2.start();
} catch (Exception e) {
// TODO: handle exception
}
}
}
-------------------------------------------------------------
요렇게 두개 만들면 다르다.
-------------------------------------------------------------
public class HelloWorld {
private static final double a = 0;
public HelloWorld() {
IamFine t1 = new IamFine();
IamFine t2 = new IamFine();
try {
t1.start();
t2.start();
} catch (Exception e) {
// TODO: handle exception
}
}
class IamFine extends Thread {
public IamFine () {
}
public void run() {
while (true) {
System.out.println("Current Count = " + a);
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
new HelloWorld();
}
}
-----------------------------------------------------------
쓰레드 구분해서 만들려고 내부 클레스로 바꾸었다.
--------------------------------------------------
public class HelloWorld {
private static final double a = 0;
public HelloWorld() {
IamFine t1 = new IamFine("first");
IamFine t2 = new IamFine("second");
try {
t1.start();
t2.start();
} catch (Exception e) {
// TODO: handle exception
}
}
class IamFine extends Thread {
String name;
public IamFine (String name) {
this.name = name;
}
public void run() {
while (true) {
System.out.println(name + "'s Current Count = " + a);
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
new HelloWorld();
}
}
------------------------------------------------
요렇게 이름을 넣을 수 있게 만들었다.
실행을 해 보면 first랑 second가 번갈아 가면서 나오는데
순서가 정확하지 않다는 것을 알 수 있다. 그건 중요한게 아닌데
값이 깨지는 것이다. ㅠㅠ
------------------------------------------------
public class HelloWorld {
private static double a = 0;
public HelloWorld() {
IamFine t1 = new IamFine("first");
IamFine t2 = new IamFine("second");
try {
t1.start();
t2.start();
} catch (Exception e) {
// TODO: handle exception
}
}
class IamFine extends Thread {
String name;
public IamFine (String name) {
this.name = name;
}
public void run() {
while (true) {
HelloWorld.a +=0.01;
System.out.println(name + "'s Current Count = " + a);
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
new HelloWorld();
}
}
---------------------------------------------
오옷... RACE CONDITION의 정석적인 예제가 되었다.
a 값을 서로 바꾸려고 하기 때문에 조금 실행하다 보면
숫자가 틀어져 버린다.
synchronized (this) {
HelloWorld.a +=0.01;
}
요렇게 해도 마찬가지.
synchronized (java.lang.Object.class) {
HelloWorld.a +=0.01;
}
요것도 안 먹는다.
---------------------------------------------
private static volatile double a = 0;
요렇게 바꾸어 주면 좀 낫다. 그래도 안 깨어지는 것은 아니다.
private volatile static double a = 0;
혹시나 이러면 더 괜찮을까?
똑같다.
---------------------------------------------
volatile 써도 synchronized 써도... 해결이 안된다.
--------------------------------------------
public class HelloWorld {
private static volatile double a = 0;
public HelloWorld() {
IamFine t1 = new IamFine("first");
IamFine t2 = new IamFine("second");
try {
t1.start();
t2.start();
} catch (Exception e) {
// TODO: handle exception
}
}
class IamFine extends Thread {
String name;
public IamFine (String name) {
this.name = name;
}
public void run() {
while (true) {
synchronized (java.lang.Object.class) {
//synchronized (IamFine.class) {
a +=0.01;
System.out.println(name + "'s Current Count = " + a);
}
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
new HelloWorld();
}
}
-----------------------------------------
안되는 이유를 알았다... double에 +0.1 자체가 문제였다.
역시 소숫점은 쓰면 안되 ㅠㅠ
런 에이블로 한번 바꾸어 보고 배운거 정리하면.
---------------------------------------------
public class HelloWorld {
// private static volatile int a = 0;
private static int a = 0;
public HelloWorld() {
Thread t1 = new Thread(new IamFine("first"));
Thread t2 = new Thread(new IamFine("second"));
try {
t1.start();
t2.start();
} catch (Exception e) {
// TODO: handle exception
}
}
class IamFine implements Runnable {
String name;
public IamFine (String name) {
this.name = name;
}
public void run() {
while (true) {
synchronized (java.lang.Object.class) {
a += 1;
System.out.println(name + "'s Current Count = " + a);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
System.out.println("Hello World.");
new HelloWorld();
}
}
---------------------------------------------
이대로 하면 숫자가 겹치는 일 없이 잘된다. 결국 volatile 을 안 쓰더라도
값을 넣는 부분과 출력 부분을 synchronized (java.lang.Object.class)로 처리해 버리면 되는 것이었다.
java.lang.Orbject.class 사랑하게 될 것 같아... ㅋㅋ
피드 구독하기:
댓글 (Atom)
UPBIT is a South Korean company, and people died of suicide cause of coin investment.
UPBIT is a South Korean company, and people died of suicide cause of coin. The company helps the people who control the market price manipu...
-
프루나는 이제 믿을만한 공유가 안되고 있다. 젠장. 영화 다운 받아보면 전부 야동이나 포르노류 밖에는 없다. 신고되어 있는 자료부터 보지만 신고가 안되어 있는 것은 제대로 다운도 되지 않는다. 이젠 유료 사이트를 믿을 수 밖엔... ...
-
Intel의 새로운 MMX - "KNI" KNI 는 Katmai New Instruction 의 약자이다 . 아는 분들은 잘 알고있겠지만 KATMAI( 이하 카트마이로 부름 ) 는 인텔의 다음번 펜티엄...
-
C:\program files\ 베이비론 폴더가 있다. 브라우저 창 다닫고 지우고 다시 실행하면 없어진다.
댓글 없음:
댓글 쓰기
국정원의 댓글 공작을 지탄합니다.