[Android 동시 프로 그래 밍]스 레 드 간 통신 의 세 가지 기본 방식

6697 단어 android
1.파이프 흐름 파이프 사용
"파이프"는 java.io 패키지 의 일부분 입 니 다.그것 은 자바 의 특성 이지 안 드 로 이 드 특유 의 것 이 아니다.하나의 파이프 가 두 라인 을 위해 단 방향 통 로 를 만든다.생산 자 는 데 이 터 를 쓰 고 소비 자 는 데 이 터 를 읽 는 것 을 책임 진다.
다음은 파이프 흐름 을 이용 하여 통신 을 하 는 예 이다.
public class PipeExampleActivity extends Activity {

    private static final String TAG = "PipeExampleActivity";
    private EditText editText;

    PipedReader r;
    PipedWriter w;

    private Thread workerThread;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        r = new PipedReader();
        w = new PipedWriter();

        try {
            w.connect(r);
        } catch (IOException e) {
            e.printStackTrace();
        }

        setContentView(R.layout.activity_pipe);
        editText = (EditText) findViewById(R.id.edit_text);
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                try {
                    if(count > before) {
                        w.write(charSequence.subSequence(before, count).toString());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });

        workerThread = new Thread(new TextHandlerTask(r));
        workerThread.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        workerThread.interrupt();
        try {
            r.close();
            w.close();
        } catch (IOException e) {
        }
    }

    private static class TextHandlerTask implements Runnable {
        private final PipedReader reader;

        public TextHandlerTask(PipedReader reader){
            this.reader = reader;
        }
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()){
                try {
                    int i;
                    while((i = reader.read()) != -1){
                        char c = (char) i;
                        
                        Log.d(TAG, "char = " + c);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

이 예 에서 EditText 에 TextWatcher 감청 을 설정 하고 EditText 의 내용 이 바 뀌 면'파이프'에 문 자 를 입력 합 니 다.이것 이 바로 생산자 입 니 다.이 동시에 파이프 에서 문 자 를 읽 는 작업 스 레 드 가 있 는데 이것 이 바로 소비자 이다.이렇게 해서 UI 스 레 드 와 작업 스 레 드 간 의 데이터 통신 을 실현 했다.
2.공유 메모리
여러 스 레 드 가 같은 메모 리 를 공유 합 니 다.즉,하나의 변 수 는 여러 스 레 드 에 동시에 접근 할 수 있 습 니 다.이곳 은 동기 화 와 원자 조작 문제 에 특히 주의해 야 한다.
자바 의 가장 기본 적 인 동기 화 예.
synchronized(this) {
    while(isConditionFullfilled == false) {
        wait();
    }


    notify();
}

wait/notify 를 사용 하 는 것 이 귀 찮 으 면 자바 가 제공 하 는 BlockingQueue 를 사용 하면 이름 에서 차단 대기 열 임 을 알 수 있 습 니 다.아래 의 예 를 보시오.
public class ConsumerProducer {
    private final int LIMIT = 10;
    private BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>(LIMIT);
    
    public void produce() throws InterruptedException {
        int value = 0;
        while (true) {
            blockingQueue.put(value++);
        }
    }
    
    public void consume() throws InterruptedException {
        while (true) {
            int value = blockingQueue.take();
        }
    }

}

3.Hander 와 Message 사용
Handler 의 메커니즘 은 인터넷 에 많은 튜 토리 얼 이 있 는데 잘 모 르 는 친구 들 에 게 구 글 을 해 볼 수 있 습 니 다.
나 는 간략 한 총 결 을 하 겠 다.
하나의 스 레 드 는 하나의 Looper 에 대응 합 니 다.하나의 Looper 는 하나의 Message Queue 를 가지 고 있 습 니 다.하나의 Looper 는 여러 개의 Handler 와 연결 할 수 있 고 하나의 Message Queue 에는 여러 개의 Message 가 포함 되 어 있 습 니 다.
다음은 Handler 를 사용 한 예 입 니 다.
public class HandlerExampleActivity extends Activity {

    private final static int SHOW_PROGRESS_BAR = 1;
    private final static int HIDE_PROGRESS_BAR = 0;
    private BackgroundThread mBackgroundThread;

    private TextView mText;
    private Button mButton;
    private ProgressBar mProgressBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_example);

        mBackgroundThread = new BackgroundThread();
        mBackgroundThread.start();

        mText = (TextView) findViewById(R.id.text);
        mProgressBar = (ProgressBar) findViewById(R.id.progress);
        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBackgroundThread.doWork();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mBackgroundThread.exit();
    }

    private final Handler mUiHandler = new Handler() {
        public void handleMessage(Message msg) {

            switch(msg.what) {
                case SHOW_PROGRESS_BAR:
                    mProgressBar.setVisibility(View.VISIBLE);
                    break;
                case HIDE_PROGRESS_BAR:
                    mText.setText(String.valueOf(msg.arg1));
                    mProgressBar.setVisibility(View.INVISIBLE);
                    break;
            }
        }
    };

    private class BackgroundThread extends Thread {

        private Handler mBackgroundHandler;

        public void run() {
            Looper.prepare();
            mBackgroundHandler = new Handler();
            Looper.loop();
        }

        public void doWork() {
            mBackgroundHandler.post(new Runnable() {
                @Override
                public void run() {
                    Message uiMsg = mUiHandler.obtainMessage(SHOW_PROGRESS_BAR, 0,
                            0, null);
                    mUiHandler.sendMessage(uiMsg);

                    Random r = new Random();
                    int randomInt = r.nextInt(5000);
                    SystemClock.sleep(randomInt);

                    uiMsg = mUiHandler.obtainMessage(HIDE_PROGRESS_BAR, randomInt,
                            0, null);
                    mUiHandler.sendMessage(uiMsg);
                }
            });
        }

        public void exit() {
            mBackgroundHandler.getLooper().quit();
        }
    }
}

좋은 웹페이지 즐겨찾기