기초적인 스레드 입니다. 개념을 이해하고 간단히 작성해서 확인해보는 정도로 괜찮을 것 같습니다.
- Thread 클래스를 상속받고 run()메서드를 오버라이딩해서 정의한 후 실행
- Runnable 인터페이스를 확장해 run()메서드를 구현해 정의한 후 실행
쓰레드를 생성할 때는 Runnable 인터페이스를 상속한 Runnable 객체를 생성시키는 방법을 사용하는 것이 유연한 코딩 방법입니다.
왜냐하면 자바는 다중상속을 지원하지 않기 때문에 상속은 하나의 클래스만 받을 수 있습니다. 또한 내가 받고 싶지 않은 메서드도 상속을 통해서 받게 되는 경우도 있습니다. 상속을 하게되면 private이 아닌 메서드나 변수를 자식 클래스가 받게 되고 그로 인해 재정의되거나 코드가 길어지고 낭비되는 문제가 생길 수 있습니다.
따라서 Runnable 인터페이스를 확장하는 것이 필요한 기능만 갖게 되고 클래스간의 결합도도 낮춰 객체지향적으로 좋습니다.
1. xml 코드 입니다
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/mainvalue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="메인스레드 값"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/backvalue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="작업스레드 값"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/increase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="메인스레드 값 증가" />
</LinearLayout>
2. extends Thread 코드
public class MainActivity extends AppCompatActivity {
int mainValue = 0, backValue = 0;
TextView mainText, backText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainText = findViewById(R.id.mainvalue);
backText = findViewById(R.id.backvalue);
// 일반적인 자바 프로그래밍에서는 메인스레드가 종료되면, 작업스레드도 종료됩니다
// 안드로이드 액티비티에선 메인스레드가 종료되도 (어플이 종료되도) 작업스레드가
// 종료되지 않는 경우가 있습니다. 그래서 setDaemon(true) 메소드를 통해
// 메인스레드와 종료 동기화를 시킵니다.
BackThread thread = new BackThread(); // 작업스레드 생성
thread.setDaemon(true); // 메인스레드와 종료 동기화
thread.start(); // 작업스레드 시작 -> run() 이 작업스레드로 실행됨
}
public void mOnClick(View v) {
mainValue++;
mainText.setText("메인스레드 값: " + mainValue);
backText.setText("작업스레드 값: " + backValue);
}
class BackThread extends Thread {
// Thread 를 상속받은 작업스레드 생성
@Override
public void run() {
while (true) {
backValue++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class MainActivity extends AppCompatActivity {
int mainValue = 0, backValue = 0;
TextView mainText, backText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainText = findViewById(R.id.mainvalue);
backText = findViewById(R.id.backvalue);
// 일반적인 자바 프로그래밍에서는 메인스레드가 종료되면, 작업스레드도 종료됩니다
// 안드로이드 액티비티에선 메인스레드가 종료되도 (어플이 종료되도) 작업스레드가
// 종료되지 않는 경우가 있습니다. 그래서 setDaemon(true) 메소드를 통해
// 메인스레드와 종료 동기화를 시킵니다.
BackThread thread = new BackThread(); // 작업스레드 생성
thread.setDaemon(true); // 메인스레드와 종료 동기화
thread.start(); // 작업스레드 시작 -> run() 이 작업스레드로 실행됨
}
public void mOnClick(View v) {
mainValue++;
mainText.setText("메인스레드 값: " + mainValue);
backText.setText("작업스레드 값: " + backValue);
}
class BackRunnable implements Runnable {
// Thread 때와 마찬가지로 run() 메소드 구현
@Override
public void run() {
while(true) {
backValue++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}