使用notify()报错跳出问题
老师您好,程序去掉notify其他部分都正常运行,只要触发notify就跳出,麻烦您帮我看一下,下面是我的线程类和主activity. 另外有很多注释的代码您直接忽略就好。
package com.example.zuoye_3_1;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.NonNull;
//线程类
public class gamethread implements Runnable {
//声明地鼠xy轴变量和一个handler
private int xcoordinate;
private int ycoordinate;
private Handler handler1;
// private Handler handler2=new Handler(){ public void handleMessage(@NonNull Message msg) {
// super.handleMessage(msg);
// gamethread.this.notifyAll();
//// Toast.makeText(MainActivity.this, "1"+msg.arg1+msg.arg2,Toast.LENGTH_SHORT).show();
//
// }};
//构造方法传handler.
public gamethread(Handler handler){
this.handler1=handler;
}
//线程,随机数字传给主线程改地鼠位置。
@Override
public void run() {
for(int i =0;i<10;i++) {
this.xcoordinate = (int) (Math.random() * 300);
this.ycoordinate = (int) (Math.random() * 600);
Message coordinate = new Message();
// coordinate.obj=this.handler2;
coordinate.arg1 = this.xcoordinate;
coordinate.arg2 = this.ycoordinate;
coordinate.what = 1;
handler1.sendMessage(coordinate);
// try {
//
// Thread.sleep((int) ((Math.random() * 500)+500));
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//调用wait延迟地鼠换位时间。
synchronized (this){
try {
this.wait(3000);
// a.wait((long) ((Math.random() * 500)+500));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package com.example.zuoye_3_1;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
//主activity.
public class MainActivity extends AppCompatActivity {
//声明图片按钮等组件,k为记录打地鼠的数量
public ImageView target;
public Button gamebutton;
public TextView gametextView;
public int k=0;
//用来负责传递数据修改地鼠位置的handler
private Handler handler1=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
target.setX(msg.arg1);
target.setY(msg.arg2);
// handler2=(Handler)msg.obj;
// Toast.makeText(MainActivity.this, "1"+msg.arg1+msg.arg2,Toast.LENGTH_SHORT).show();
}
};
// private Handler handler2;
Thread a;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//实例化
target=(ImageView)findViewById(R.id.target);
gamebutton =(Button)findViewById(R.id.gamebutton);
gametextView=findViewById(R.id.gametextView);
}
//用来调用gamethread线程,修改组件文字的方法
public void gameT() {
gamebutton.setEnabled(false);
gamebutton.setText("游戏中");
gametextView.setText("开始啦");
a= new Thread(new gamethread(handler1));
a.start();
// synchronized (a){
// try {
// a.wait();
//// a.wait((long) ((Math.random() * 500)+500));
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
//用来对按钮做判断的方法。
public void gamestart(View v){
switch (v.getId()){
case R.id.gamebutton:
gameT();
break;
case R.id. target:
// handler2.sendEmptyMessage(1);
k++;
gametextView.setText("打到"+k+"只,共十只");
//
//本意为在点击地鼠时,解开gamethread循环中的wait()延迟,使地鼠换位置,但是点击直接报错,Caused by: java.lang.IllegalMonitorStateException: object not locked by thread before notify()
a.notify();
break;
}
}
}
正在回答
1)同学理解错了:为什么要notify(),就是被锁定了synchronized。要保证你调用的notify 的对象,是你synchronized 的对象。才不会object not locked by thread before notify()。 2)对于作业不需要锁定,地鼠要一个一个的出,出完一个,再出第二个,并不是10只地鼠同时出的,所以你不用锁,也不用notify()。祝:学习愉快
相似问题
登录后可查看更多问答,登录/注册
- 参与学习 人
- 提交作业 220 份
- 解答问题 1800 个
本阶段是联网及数据处理的必备技能。课程从网络基础知识到线程间协同工作、异步下载处理;从文件存储、到轻量级数据库SQLite的使用;最后利用最流程的第三方框架助你快速开发企业级APP。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星