Android/Java
[Java] Synchronized
혀가 길지 않은 개발자
2020. 7. 27. 18:35
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String name;
MainActivity person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
person = new MainActivity();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.whoAmI("혀가 길지 않은 개발자");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.whoAmI("혀가 긴 개발자");
}
}
}).start();
}
public void whoAmI(String name) {
try {
this.name = name;
long waiting = (long) (Math.random() * 100);
Thread.sleep(waiting);
if (!this.name.equals(name)) {
Log.e("", this.name + " != " + name);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String name;
MainActivity person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
person = new MainActivity();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.whoAmI("혀가 길지 않은 개발자");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.whoAmI("혀가 긴 개발자");
}
}
}).start();
}
public synchronized void whoAmI(String name) {
try {
this.name = name;
long waiting = (long) (Math.random() * 100);
Thread.sleep(waiting);
if (!this.name.equals(name)) {
Log.e("", this.name + " != " + name);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void whoAmI(String name) 에서
public synchronized void whoAmI(String name) 로 수정
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String food;
MainActivity person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
person = new MainActivity();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.eatPizza();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.eatHamburger();
}
}
}).start();
}
public void eatPizza() {
try {
this.food = "Pizza";
long waiting = (long) (Math.random() * 100);
Thread.sleep(waiting);
if (!this.food.equals("Pizza")) {
Log.e("", this.food + " != Pizza");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void eatHamburger() {
try {
this.food = "Hamburger";
long waiting = (long) (Math.random() * 100);
Thread.sleep(waiting);
if (!this.food.equals("Hamburger")) {
Log.e("", this.food + " != Hamburger");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String food;
MainActivity person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
person = new MainActivity();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.eatPizza();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person.eatHamburger();
}
}
}).start();
}
public synchronized void eatPizza() {
try {
this.food = "Pizza";
long waiting = (long) Math.random() * 100;
Thread.sleep(waiting);
if (!this.food.equals("Pizza")) {
Log.e("", this.food + " != Pizza");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void eatHamburger() {
try {
this.food = "Hamburger";
long waiting = (long) Math.random() * 100;
Thread.sleep(waiting);
if (!this.food.equals("Hamburger")) {
Log.e("", this.food + " != Hamburger");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
synchronized 추가
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String food;
MainActivity person1;
MainActivity person2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
person1 = new MainActivity();
person2 = new MainActivity();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person1.eatPizza();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0; i<1000; i++) {
person2.eatHamburger();
}
}
}).start();
}
public void eatPizza() {
try {
this.food = "Pizza";
long waiting = (long) Math.random() * 100;
Thread.sleep(waiting);
if (!this.food.equals("Pizza")) {
Log.e("", this.food + " != Pizza");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void eatHamburger() {
try {
this.food = "Hamburger";
long waiting = (long) Math.random() * 100;
Thread.sleep(waiting);
if (!this.food.equals("Hamburger")) {
Log.e("", this.food + " != Hamburger");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
객체 2개 생성
MainActivity person1;
MainActivity person2;
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Integer> list;
private int tryCount = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<>();
Log.e("", "start!");
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
pushNumber(i);
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
pushNumber(i);
}
}
});
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("", "End! " + list.size());
}
void pushNumber(int number) {
Log.e("", Integer.toString(tryCount++));
if (!list.contains(number)) {
list.add(number);
}
}
}
카운트 총합이 20000미만인 이유는 첫 번째 스레드가 49에서 50으로 증가하는 타이밍에 두 번째 스레드에서 48에서 49로 증가하게 되면 카운트 총합은 감소하게 된다.
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Integer> list;
private int tryCount = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<>();
Log.e("", "start!");
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
pushNumber(i);
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
pushNumber(i);
}
}
});
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("", "End! " + list.size());
}
void pushNumber(int number) {
Log.e("", Integer.toString(tryCount++));
synchronized (this) {
if (!list.contains(number)) {
list.add(number);
}
}
}
}
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
int count1 = 0;
int count2 = 0;
MainActivity stopWatch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stopWatch = new MainActivity();
Long startTime = System.currentTimeMillis();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
stopWatch.addCount1();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
stopWatch.addCount2();
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Long endTime = System.currentTimeMillis();
Long elapsedTime = endTime - startTime;
Log.e("소요시간 : ", Long.toString(elapsedTime));
}
public synchronized void addCount1() {
Log.e("", "count1 : " + this.count1++);
}
public synchronized void addCount2() {
Log.e("", "count2 : " + this.count2++);
}
}
MainActivity.java
package com.jwsoft.javaproject;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
int count1 = 0;
int count2 = 0;
MainActivity stopWatch;
private final Object object1 = new Object();
private final Object object2 = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stopWatch = new MainActivity();
Long startTime = System.currentTimeMillis();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
stopWatch.addCount1();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=1; i<=10000; i++) {
stopWatch.addCount2();
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Long endTime = System.currentTimeMillis();
Long elapsedTime = endTime - startTime;
Log.e("소요시간 : ", Long.toString(elapsedTime));
}
public void addCount1() {
synchronized (object1) {
Log.e("", "count1 : " + this.count1++);
}
}
public void addCount2() {
synchronized (object2) {
Log.e("", "count2 : " + this.count2++);
}
}
}
synchronized (object1) 로 수정
synchronized (object2) 로 수정
위의 경우보다 효율이 좋음