线程不会进入同步块

时间:2015-01-10 13:48:00

标签: java android multithreading synchronized

我的Android应用程序中有一个Button,它必须在按住它的同时运行连续动作,因为我创建了一个onTouchListener来处理这个问题,我的结构是在捕获ACTION_DOWN事件时的一个线程使用while(true)循环运行,然后当通过ACTION_UP捕获该线程停止的wait()事件以便在按住时再次循环时,问题是当尝试执行时thread.wait()线程没有进入同步块并且不会等待,但是它会停止执行该线程中存在的runOnUIThread,并且在我按下任何按钮之后应用程序崩溃并给我ANR Exception : Input dispatching timed out

   // the thread declaratrion
    test = new Thread(new Runnable() {

        @Override
        public void run() {

            while (true) {
                // still loops here
                value = value + 1;
                runOnUiThread(new Runnable() {
                    public void run() {
                        // doesn't go here anymore
                        mTextView.setText(Integer.toString(value));
                    }
                });
                // still loops here
                synchronized (test) {
                    try {
                        Thread.sleep(150);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

            }
        }
    });

    // the onTouchListener
    case MotionEvent.ACTION_DOWN:
        if (!test.isAlive()) {
            synchronized (test) {
                test.start();
            }
        } else {
            synchronized (test) {
                test.notify();
            }
        }
        break;
    case MotionEvent.ACTION_UP:
        // accepts the action
        synchronized (test) {
            try {
                // doesn't goes here
                test.wait(); // doesn't execute
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        break;
    default:
        break;

2 个答案:

答案 0 :(得分:0)

可能您使用的API太低,无法满足您的需求。只需查看http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html

即可

答案 1 :(得分:0)

我看到的一件事是潜在危险的是,在你的单独线程中,你在同步语句中等待。因此,当那个人正在睡觉时,它会锁定他,因此在你的onTouchListener中,没有人可以抓住锁而是等待。并且因为onTouchListener是在框架中控制的,所以如果它等待太久,它可能会停止运行。我做了一个简单的测试here来证明它。

class Ideone
{
        public static void main (String[] args) throws java.lang.Exception
    {
        final Object globalLock = new Object();
        Thread t1  = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (globalLock) {
                    System.out.println("thread1 grabbed the lock.");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("thread1 returned the lock.");
                }
            }
        });
        t1.start();

        Thread.sleep(200);

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread2 is waiting for the lock...");
                synchronized (globalLock) {
                    System.out.println("thread2 got the lock");
                }
            }
        });
        t2.start();
        t1.join();
        t2.join();
    }
}