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...
-
연휴 마지막날 아침... 산책을 하다 한장 찍어보았다. 인생도 마찬가지로 길의 끝을 모른체 선택을 해야하는 경우가 발생한다. 나중에 그 기준이 바뀔수도 있지만. 지금 기준은 많은 사람이 함께 갈 수 있는 길을 선택하고 싶다.
-
□ native modifier 는 자바가 아닌 다른 언어로 작성된 코드를 자바에서 사용하기 위한 것 □ transient modifier 는 객체가 직렬 화되는 과정에서 해당 필드가 저장되지 않아야 한다는 것을 알리기 위해 사용 ...
-
제로보드 세팅. sudo apt-get install apache2 mysql-server libapache2-mod-php5 phpmyadmin ssh 패키지를 이용한 소프트웨어 설치 - APM세팅 및 ssh 설치 ...
댓글 없음:
댓글 쓰기
국정원의 댓글 공작을 지탄합니다.