关于Android中的另类同步问题 ----在有Handler的情况下去使用线程同步,waitDone

news/2024/7/7 5:29:33 标签: 线程, android, handler, wait, notify

关于Android中使用Handler部分的同步,首先简单说一下线程同步的问题吧,什么是同步??

同步就是互斥+顺序,也就是一个线程的执行依赖于另外一个线程执行的结果

引用一个今天在查看Camera相关代码的时候,遇到的一个Handler使用的同步问题:

某个方法的执行依赖于Handler中的执行的结果:

package com.example.androidtestdemo;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    int resultCount = 0;
    Handler mCameraHandler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            Log.i(TAG, "MSG:"+msg.what);
            switch (msg.what) {
            case 1:
                try {
                    Log.i(TAG, "start sleep 5s");
                    Thread.sleep(5000);
                    Log.i(TAG, "end sleep 5s");
                    resultCount = 10;
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
            case 2:
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Log.i(TAG, "========2");
                break;
            default:
                break;
            }
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                Log.i(TAG, "resultCount1:"+resultCount);
                 check1();
//               check2();
                 Log.i(TAG, "resultCount2:"+resultCount);
            }
        }).start();

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    public void check1(){
        mCameraHandler.sendEmptyMessage(1);
        waitDone();
    }


    public void check2(){
        mCameraHandler.sendEmptyMessage(2);
        waitDone();
    }

    static int count = 0;


    private boolean waitDone() {
         final Object waitDoneLock = new Object();
        Log.i(TAG, "waitDownLock:"+waitDoneLock.toString());
        final Runnable unlockRunnable = new Runnable() {
            @Override
            public void run() {
                synchronized (waitDoneLock) {
                    Log.i(TAG, "start notify"+System.currentTimeMillis());
                    waitDoneLock.notifyAll();
                    Log.i(TAG, "end notify"+System.currentTimeMillis());
                }
            }
        };
        synchronized (waitDoneLock) {
            count++;
            mCameraHandler.post(unlockRunnable);
            try {
                Log.i(TAG, "start wait:"+System.currentTimeMillis());
                waitDoneLock.wait();
                Log.i(TAG, "end wait:"+System.currentTimeMillis());
                Log.i(TAG, "resultCount3:"+count);
            } catch (InterruptedException ex) {
                Log.v(TAG, "waitDone interrupted");
                return false;
            }
        }
        return true;
    }

}

其实刚开始在看到这个waitDone的时候,完全处于一种懵逼状态,一看没看懂。什么个鸟意思,每个方法执行的时候都需要去重新new出来一个新的锁,谈不上线程同步锁,但是多出来的是waitnotify的方法。也很是纳闷,后来简单搜了一下关于这个mHandler.post,原来这个方法是在mHandler执行完线程中的任务后,再紧接着去执行的,也就是handler.post这个方法的执行是sendEmptyMessage执行之后。

所以这个notify也就是在mHandler之后去等待线程中的任务

举个最简单的例子:

一个全局变量,他的计算都是在Handler中的,但是使用是在Handler以外的方法中去使用,那么这个时候就可以去使用waitnotify的形式去进行同步,这样足以确保是计算结束以后执行操作。

http://www.niftyadmin.cn/n/783711.html

相关文章

mysql中文乱码

mysql出现中文乱码后,在导库语句中加入字符集设置即可 导出mysqldump -h127.0.0.1 -P3307 -uroot -p --default-character-setutf8 cc>cc.sql导入mysql -uroot -p --default-character-setutf8 效果图 转载于:https://www.cnblogs.com/--zl--/p/9781709.html

ndk学习之c++语言基础复习----C++线程与智能指针

线程 线程,有时被称为轻量进程,是程序执行的最小单元。 C11线程: 我们知道平常谈C线程相关的东东基本都是基于之后要学习的posix相关的,其实在C11有自己新式创建线程的方法,所以先来看一下,看在C11中如何来创建一个线的…

Linux线程浅析[线程的同步和互斥之线程同步的条件变量pthread_cond_t]

Linux线程浅析[线程的同步和互斥之线程同步的条件变量] 线程同步的条件变量 经典的写者和读者的同步问题 线程同步的条件变量 线程同步—–条件变量 互斥锁的特点就是它只有两种状态:锁定和非锁定 条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了…

MQTT异步使用

目录1:结构体1.1:MQTTAsync1.2:MQTTAsync_connectOptions1.3:MQTTAsync_disconnectOptions1.4:MQTTAsync_responseOptions1.5:MQTTAsync_message2:接口函数2.1: MQTTAsync_create2.2: MQTTAsync…

Linux线程浅析[线程的同步和互斥之线程信号量]

Linux线程浅析[线程的同步和互斥之线程信号量] 什么是线程信号量线程信号量的相关函数使用信号量来进行互斥和同步的问题 什么是线程信号量 在之前有一篇博客讲了进程的信号量,sing&#xff4…

数组练习

1、按指定格式打印数组 指定数组为:[11, 33, 44, 22, 55] 2、数组逆序排列 3、数组的选择排序 4、冒泡排序 5、二分查找 转载于:https://www.cnblogs.com/alphajuns/p/9786616.html

Linux线程浅析[线程的同步和互斥之线程死锁,线程与信号的关系]

Linux线程浅析[线程的同步和互斥之线程死锁,线程与信号的关系] 线程死锁线程与信号 记得以前在学习java线程的时候,也会接触死锁,当时不断强调锁千万不要不能去做嵌套,不然容易一个线程在执行的时候所需要的锁被别的线程持有了,而别的线程执行的时候,它的锁又被第一个线程持有…

Codeforces 1064D Labyrinth(双端队列BFS)

题意: 给一个图,"*"不可以走,给你一个起点,限制向左走L次,向右走R次,上下不限制,问你最多可以走到多少个格子 思路: BFS,每次将上下走的策略加入队首&#xff…