반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함


Using Multiple Threads



이번에는 두개의 쓰레드를 실행시키는 것에 대해 알아 보겠습니다. 두개의 쓰레드를 통해서 어떻게 두개의 태스크가 동기적으로 실행되는지에 대해 보게 될 겁니다. 이 두개의 쓰레드에 대해 한개의 핸들러를 생성할 겁니다. 이 쓰레드들은 1에서부터 10까지의 순차적인 숫자를 표시합니다. 첫번째 쓰레드가 1초에 숫자 하나씩 1에서부터 10까지 차례대로 표시를 하고 두번째 쓰레드는 2초에 한번씩 1부터 10까지 차례대로 표시를 합니다.


이 두 쓰레드들은 동기적으로 task를 시작할 겁니다. 하지만 첫번째 쓰레드가 먼저 끝나겠죠. 두 번째 쓰레드가 끝나는 시간의 딱 반만 소요 될 겁니다.



handleMessage() 메소드는 이 순차적인 번호를 표시하기 위해 핸들어 안에서 오버라이드 될 겁니다. 순차적인 번호들은 Message 파라미터를 통해서 이 메소드에 넘겨집니다. 이 두 쓰레드의 Message object를 구별하기 위해서 Message object내의 calling 쓰레드 이름이 Bundle 에서 명명 됩니다. 



이 앱을 만들기 위해서 layout xml 에는 4개의 TextView 가 들어가게 됩니다. 두개는 쓰레드 이름이 표시될 거고 두개는 그 값이 표시될 겁니다. 




activity_multiple_threads_app.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MultipleThreadsAppActivity" >
    <TextView
        android:id="@+id/thread1" 
        android:text="Thread1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dip" 
        android:layout_marginLeft="20dip"
        android:textSize="@dimen/text_size"
        android:textStyle="bold" />
       <TextView
        android:id="@+id/thread2" 
        android:text="Thread2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dip" 
        android:layout_marginLeft="100dip"
        android:layout_toRightOf="@id/thread1"
        android:textSize="@dimen/text_size"
        android:textStyle="bold"/>
    <TextView
        android:id="@+id/seqnums1" 
        android:text="0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dip" 
        android:layout_marginLeft="30dip"
        android:layout_below="@id/thread1"
        android:textSize="@dimen/text_size"
        android:textStyle="bold" />
   <TextView
        android:id="@+id/seqnums2" 
        android:text="0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dip" 
        android:layout_marginLeft="150dip"
        android:layout_below="@id/thread2"
        android:layout_toRightOf="@id/seqnums1" 
        android:textSize="@dimen/text_size"
        android:textStyle="bold" />

</RelativeLayout>



각각 id를 갖고 있고 이 id로 나중에 자바 파일에서 각 TextView를 구분해서 활용할 겁니다.
그리고 textSize는 dimention 에서 정의된 text_size를 사용할 거구요.
이 값은 res/values 폴더 안에 dimens.xml 이라는 파일 안에 있습니다.



그 다음에 핸들러를 정의하고  이 두 쓰레드들의 메세지를 보내고 받기 위해 아래와 같이 자바파일을 만듭니다.


MultipleThreadsAppActivity.java



public class MultipleThreadsAppActivity extends Activity {
static    private TextView seqNums1, seqNums2;
       
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multiple_threads_app);
        seqNums1 = (TextView)findViewById(R.id.seqnums1);
        seqNums2 = (TextView)findViewById(R.id.seqnums2);
    }
   
static    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg)        {
            String threadInvoked=msg.getData().getString("threadName");
            if (threadInvoked.equals("thread1"))
        seqNums1.setText(msg.obj.toString());
            if (threadInvoked.equals("thread2"))
                seqNums2.setText(msg.obj.toString());
        }
        };

        @Override
        protected void onStart() {
            super.onStart();
     Thread     thread1 = new Thread(new Runnable() {
        @Override
        public void run() {
             try {
           for(int i=1;i<=10;i++){
                                Thread.sleep(1000);
                                Message msg = new Message(); 
                                Bundle bundle = new Bundle();
                                bundle.putString("threadName", "thread1");
                                msg.setData(bundle);
                                msg.obj=String.valueOf(i);
                                handler.sendMessage(msg);
       }
                            } catch (InterruptedException e) {
                               e.printStackTrace();
                            }   
        }
        });

 Thread thread2 = new Thread(new Runnable()        {
    @Override
        public void run() {
         try {
           for(int i=1;i<=10;i++){
                                 Message msg = new Message();
                                Thread.sleep(2000);
                                Bundle bundle = new Bundle();
                                bundle.putString("threadName", "thread2");
                                msg.setData(bundle);
                                msg.obj=String.valueOf(i);
                                handler.sendMessage(msg);
           }
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
        }
        });
 thread1.start();
 thread2.start();
    }
}



onCreate() 메소드를 보면 숫자가 들어갈 TextView의 객체들을 만들었습니다. 다음에 onStart() 메소드를 보면 Thread class를 사용하는 걸 보실 수 있습니다. 두개의 쓰레드를 만들어서 두개의 runnable object에 사용하고 있습니다. 1에서부터 10까지의 숫자를 표시하기 위해서 run() 메소드에서는 Message object를 생성했습니다. 그리고 Bundle 객체도 하나 생성해서 그 안에 쓰레드 이름을 key, value 한 쌍으로 넣었습니다. 그것을 Message에 setData()를 사용해서 세팅했습니다. 그리고 msg.obj에 숫자를 대입합니다. 그리고 마지막으로 이 메세지를 Handler object를 통해서 TextView에 전달을 하고 그 값이 화면에 뿌려지게 됩니다.
첫번째 쓰레드는 1초 간격으로 작업을 하고 두번째 쓰레드는 2초 간격으로 작업을 합니다.


이 어플리케이션을 실행하고 나면 두 쓰레드 모두 1서부터 숫자를 표시할 겁니다. 첫번째 쓰레드는 10까지 표시하는데 두번째 쓰레드보다 반 밖에 시간이 안 걸릴 겁니다.

반응형

Comment