[Android 동시 프로 그래 밍]스 레 드 간 통신 의 세 가지 기본 방식
6697 단어 android
"파이프"는 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();
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.