Java 如何同步线程:onTouchEvent和run()?
我有一个扩展了SurfaceView的GraphicView。我需要它来画图形。我也需要发泄一下。但问题是。。。我不知道如何描述:)这是我的代码: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
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 !!!!" );
}
}
}