Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何同步线程:onTouchEvent和run()?_Java_Android_Mutex_Touch Event_Runnable - Fatal编程技术网

Java 如何同步线程:onTouchEvent和run()?

Java 如何同步线程:onTouchEvent和run()?,java,android,mutex,touch-event,runnable,Java,Android,Mutex,Touch Event,Runnable,我有一个扩展了SurfaceView的GraphicView。我需要它来画图形。我也需要发泄一下。但问题是。。。我不知道如何描述:)这是我的代码: public class GraphicView extends SurfaceView implements Runnable { private boolean mutexOpened = true; public boolean onTouchEvent( MotionEvent me ) { if ( m

我有一个扩展了SurfaceView的GraphicView。我需要它来画图形。我也需要发泄一下。但问题是。。。我不知道如何描述:)这是我的代码:

public class GraphicView extends SurfaceView implements Runnable {

    private boolean mutexOpened = true;

    public boolean onTouchEvent( MotionEvent me ) {

        if ( mutexOpened ) {

            mutexOpened = false;

            Log.d( "mutex", "ACTION 1" );

            switch ( action ) {

                case MotionEvent.ACTION_DOWN: {

                    int rnd = new Random().nextInt( 40000 ) + 1000;
                    for ( int i = 0; i < rnd; i++ ) {} // it's some long action :)

                    Log.d( "mutex", "ACTION 2: down" );
                    break;

                }

            }

            Log.d( "mutex", "ACTION 2: end" );
            mutexOpened = true;

        }

    }

    public void run() {

        while ( true ) {

            if ( mutexOpened ) {        
                Log.d( "mutex", "!!! RUN !!!!" );
            }

        }

    }

}
但是为什么呢??当互斥锁关闭时,为什么第二个“!!!RUN!!!!”在“操作1”和“操作2”之间运行?这是不可能的

我试着做下一步:

public void run() {
    while ( true ) {
        if ( mutexOpened ) {
            mutexOpened = false; // close mutex
            Log.d( "mutex", "!!! RUN !!!!" );
            mutexOpened = true; // open mutex
        }
    }
}

但是。。。失败:)onTouchEvent根本不运行:D)有人知道如何解决这个问题吗?

首先,您没有描述您正在尝试做什么以及为什么

其次。您试图实现自己的互斥锁,这完全是错误的。您尝试使用的变量甚至不是线程安全的。您无法知道它在任何时间点的状态,因为多个线程可能正在访问它。您应该使用原子布尔

有关多线程的详细介绍,请参阅本幻灯片集


您必须同步对mutexOpened的访问:run()可能正在读取mutexOpened,然后将其设置为false,可能正在打印run!!!打印“操作1”后立即执行

使用Java关键字synchronized同步对mutexOpened的访问。在run()上,可以使用wait(),它在睡眠阶段释放锁

如果使用synchronized关键字,则根本不需要变量mutexOpened

public class GraphicView extends SurfaceView implements Runnable {

    synchronized public boolean onTouchEvent( MotionEvent me ) {


        Log.d( "mutex", "ACTION 1" );

        switch ( action ) {

            case MotionEvent.ACTION_DOWN: {

                int rnd = new Random().nextInt( 40000 ) + 1000;
                for ( int i = 0; i < rnd; i++ ) {} // it's some long action :)

                Log.d( "mutex", "ACTION 2: down" );
                break;

            }

        }

        Log.d( "mutex", "ACTION 2: end" );

    }


    synchronized public void run() {

        while ( true ) {
            wait(100); // Wait 100ms and release the lock
            Log.d( "mutex", "!!! RUN !!!!" );

        }

    }

}
公共类GraphicView扩展了SurfaceView实现可运行{
同步公共事件(MotionEvent me){
Log.d(“互斥”、“动作1”);
开关(动作){
case MotionEvent.ACTION\u DOWN:{
int rnd=new Random().nextInt(40000)+1000;
对于(inti=0;i

另外,尽量不要在GUI线程中执行长操作(即注释“it's some long action”):这应该在单独的线程中执行

@PBrando,我认为您理解正确。它在第二个线程上运行,但我需要同步这些线程…:)谢谢你的建议!我试图使用您的代码,但它给了我一个错误:“java.lang.IllegalMonitorStateException:对象在等待()之前未被线程锁定”,该错误是什么意思?@JavaRunner您是否将该方法声明为“已同步”运行?
public class GraphicView extends SurfaceView implements Runnable {

    synchronized public boolean onTouchEvent( MotionEvent me ) {


        Log.d( "mutex", "ACTION 1" );

        switch ( action ) {

            case MotionEvent.ACTION_DOWN: {

                int rnd = new Random().nextInt( 40000 ) + 1000;
                for ( int i = 0; i < rnd; i++ ) {} // it's some long action :)

                Log.d( "mutex", "ACTION 2: down" );
                break;

            }

        }

        Log.d( "mutex", "ACTION 2: end" );

    }


    synchronized public void run() {

        while ( true ) {
            wait(100); // Wait 100ms and release the lock
            Log.d( "mutex", "!!! RUN !!!!" );

        }

    }

}