学而实习之 不亦乐乎

Android:java.lang.IllegalMonitorStateException: object not locked by thread before notify()

2022-01-09 21:14:11

线程开发中,遇到这个问题(这其实和android开发没有关系,是有关线程的相关问题)大概代码逻辑如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public static final String EXTRA_MESSAGE = "com.example.MESSAGE";
    public static final String CHARGE_SUCCESS = "Charge successful!";

    private Button button1 = null ;
    private Button button2 = null ;
    private Button button3 = null ;
    private Button button4 = null ;
    private Button button5 = null ;
    private Button buttonOtherFee = null ;
    private TextView viewBalanceLeftValue = null;

    private BufferedReader input = null;
    private PrintStream output = null;

    private Handler handler = null;
    private static boolean sendTag = false;
    private String sendStr = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button1 = findViewById(R.id.feepolicy);
        viewBalanceLeftValue = findViewById(R.id.balanceleftvalue);

        button1.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                sendStr = "hello world!";
                Print("onClick" + sendStr);
                synchronized ((Object)sendTag) {
                    sendTag = true;
                    Print("notify" + sendStr);
                    ((Object)sendTag).notify();
                }
            }
        });

        handler = new Handler(){

            public void handleMessage(Message msg){
                if(msg.what == 1 )
                {
                    char textBalanceLeftValue[] = ((Map<String,String>)msg.obj).get("key").toCharArray();
                    viewBalanceLeftValue.setText(textBalanceLeftValue,0,textBalanceLeftValue.length);
                }
            }
        };

        Thread thread = new  Thread(){
            public void run(){

                SocketClient socketClient = new SocketClient("10.0.2.2",8888);

                try {
                    input = new BufferedReader(new InputStreamReader(socketClient.getSocket().getInputStream()));
                    output = new PrintStream( socketClient.getSocket().getOutputStream() );
                    socketClient.setInput(input);
                    socketClient.setOutput(output);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Map<String,String> mp = new HashMap<String,String>();

                 synchronized ((Object)sendTag){
                     while (true) {
                         output.write(sendStr.getBytes(), 0, sendStr.getBytes().length);
                         String result = socketClient.read();
                         mp.put("key", result);
                         Message msg = handler.obtainMessage();
                         msg.what = 1;
                         msg.obj = mp;
                         handler.sendMessage(msg);
                         try {
                             ((Object)sendTag).wait();
                         } catch (InterruptedException e) {
                             e.printStackTrace();
                         }
                     }
                 }
            }
        };
        thread.start();
    }
}

这里的锁在中间会有值的变化,因此有可能在线程运行过程中就不是一个元素了,因此会报错。把锁的类型从 boolean 修改为 Object,就ok了。