主线程是一个while(true)循环 ,并且卡在Scanner s=new Scanner(System.in);随时监听键盘输入;
子线程也是一个while(true),并且一直监听服务器发来的Message信息;
如果当服务器发来的message的类型符合条件的时候,就需要键入一定的值。
但是此时如果不阻塞主线程的话,键入的值会被主线程当作键入的值,而不是子线程的值。
大致逻辑代码如下
主线程:
//主线程
MainThread{
public static void main(String[] arg){
while(true){
ChildThread.start();
Scanner s=new Scanner(System.in);
String mainChoice=s.next();//如果不输入就一直卡在这监听键盘;
//any code
}
}
}
//子线程
ChildThread{
public static void main(String[] arg){
while(true){
//通过socket监听服务器返回的message;
if(message.type==Message.GET_MESSAGE){
//通过键入一定值对message进行处理;
Scanner s=new Scanner;
String childChoice=s.next();
//any code
}
}
}
}
是在得到服务器返回相应的值的时候,键入值时会被当作mainChoice;无报错;
有时候键入值后一直按回车,键入的值会被当作childChoice,
所以考虑是否是两个线程在抢先执行,所以就在子线程中添加了如下代码
//lock为主线程的一个元素;
synchronized(lock){
lock.wait()
}
//处理键入的值
synchronized(lock){
lock.notify();
}
在子线程得到消息的时候先阻塞主线程,然后在完成后唤醒主线程,
但是这方法结果是:
在lock.wait()执行后 ,便不会执行,
并且主线程却没有受阻塞;键入的值仍然被当做了mainchoice;
你这样设计不合理吧,应该是通过命令字来判断接收的信息,根据情况再发送对应消息。
嗯,我想可以使用Exchenger类来交换二者的参数,把二者的while条件换为一个变量。
嗯,这样的话有些麻烦,可以定义一个静态变量,加上volatile 关键字,然后用这个静态变量来控制主线程的循环
由于volatile的可见性,在子线程中修改它会使得其他线程可知,这样就可以使用wait去休眠主线程,待子线程完成后再唤醒该线程。