【问题标题】:Thread won't enter synchronized block线程不会进入同步块
【发布时间】:2015-01-10 13:48:00
【问题描述】:

我的 android 应用程序中有一个 Button,它必须在按住它的同时运行连续动作,为此我创建了一个 onTouchListener 来处理此类问题,我的结构是在一段时间内捕获 ACTION_DOWN 事件线程时( 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;

【问题讨论】:

  • 一个投反对票并没有任何帮助行动就离开的幽灵投反对票,这就是我在这里所缺少的:D

标签: java android multithreading synchronized


【解决方案1】:

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

【讨论】:

  • 我认为与其纠结于低级 API,不如使用更适合的 API
【解决方案2】:

我看到的一个潜在危险是,在您的单独线程中,您在同步语句中等待。所以当那个人睡觉时,它会带着锁,因此在你的 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();
    }
}

【讨论】:

  • 嗯,我试过这种方法,但没有解决问题。
猜你喜欢
  • 1970-01-01
  • 2015-03-02
  • 2014-04-30
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多