Java:UI线程在双线程应用程序中未恢复
我目前正在使用两个线程构建Java应用程序: 第一个线程是关于应用程序的UI,以及通过蓝牙线程接收的命令的处理 蓝牙线程是等待机器人连接并处理通信的蓝牙服务器 到目前为止,UI线程处于wait()状态,直到bluetooth线程获得要处理的新消息 问题是,我可以从蓝牙线程跟踪notify/notifyAll调用,但我的UI没有恢复其活动 我现在确信我误解了管理同步线程的正确方法,但我无法找出我的软件中的错误 以下是UI的代码:Java:UI线程在双线程应用程序中未恢复,java,multithreading,bluetooth,Java,Multithreading,Bluetooth,我目前正在使用两个线程构建Java应用程序: 第一个线程是关于应用程序的UI,以及通过蓝牙线程接收的命令的处理 蓝牙线程是等待机器人连接并处理通信的蓝牙服务器 到目前为止,UI线程处于wait()状态,直到bluetooth线程获得要处理的新消息 问题是,我可以从蓝牙线程跟踪notify/notifyAll调用,但我的UI没有恢复其活动 我现在确信我误解了管理同步线程的正确方法,但我无法找出我的软件中的错误 以下是UI的代码: package mapper; import java.awt.B
package mapper;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
public class MapperUI extends JFrame implements Runnable {
private ArrayList<String> messageArray;
public MapperUI(){
super();
build();
this.setVisible(true);
new Thread(this).start();
}
private void build(){
setTitle("SLAM Mapper");
setSize(600,500);
setLocationRelativeTo(null);
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(buildContentPane());
}
private JPanel buildContentPane(){
JPanel main = new JPanel();
main.setLayout(new BorderLayout());
//TODO Implements auto-generated map after bluetooth communication
MapPanel map = new MapPanel();
main.add(map,BorderLayout.CENTER);
//TODO This fields will be buildt with stored message
JTable positions = new JTable(15,2);
main.add(positions,BorderLayout.EAST);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
JButton bouton = new JButton("Start");
buttonPanel.add(bouton);
JButton bouton2 = new JButton("Send");
buttonPanel.add(bouton2);
main.add(buttonPanel,BorderLayout.SOUTH);
return main;
}
public synchronized void run(){
MapperCom bt = new MapperCom();
while(true){
try {
System.out.println("Mapper is Waiting......");
wait();
String message = bt.getMessage();
this.messageArray.add(message);
bt.setNextCommand(processMessage(message));
notifyAll();
System.out.println("Mapper Notify");
build();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public String processMessage(String message){
String command = "";
//TODO Build a response
command = "fffff\n";
return command;
}
}
我想当你调用
notifyAll()
时,它会调用this.notifyAll()
。没有其他元素在同一个类中等待。因此,您可以在两个类上共享同一个对象,并调用obj.wait()
和obj.notifyAll()
。它会起作用的 看看这个:
- wait()告诉调用线程放弃监视器并转到
睡眠,直到其他线程进入同一监视器并调用
通知() - notify()唤醒在上调用wait()的第一个线程 同一个物体
- notifyAll()唤醒在上调用wait()的所有线程 同样的目标。优先级最高的线程将首先运行
这是Java中对线程概念的主要误解。下面是一个示例程序。如果您希望使用wait¬ify进行通信,那么两个线程之间基本上需要一些公共锁
package ravi.tutorial.java.threads;
public class TestThreads {
/**
* @param args
*/
public static void main(String[] args) {
CommonLock commonLock = new CommonLock();
Thread1 thread1 = new Thread1(commonLock);
Thread2 thread2 = new Thread2(commonLock);
thread1.start();
thread2.start();
}
}
/*
* Common monitor lock between both threads, used for communication using wait
* notify.
*/
class CommonLock {
}
// Extending Thread instead of Runnable as its just a test
class Thread1 extends Thread {
private CommonLock commonLock;
public Thread1(CommonLock commonLock) {
this.commonLock = commonLock;
}
public void run() {
System.out.println("Started thread 1");
System.out.println("waiting thread 1");
try {
// TO wait on commonLock, first need to get lock on commonLock. SO
// put synchronized block of commonLock.
synchronized (commonLock) {
commonLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("DONE waiting thread 1 as I got notification from THread 2");
}
}
class Thread2 extends Thread {
private CommonLock commonLock;
public Thread2(CommonLock commonLock) {
this.commonLock = commonLock;
}
public void run() {
System.out.println("Running thread 2");
try {
System.out.println("Sleeping thread 2");
// Just take gap of 2 sec before notifying.
Thread.sleep(2000);
// TO notify on commonLock, first need to get lock on commonLock. SO
// put synchronized block of commonLock.
synchronized (commonLock) {
System.out.println("Notifying thread 2");
commonLock.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
绝对不要让UI线程进入等待状态。这会冻结您的GUI。非常感谢您的完整实现
package ravi.tutorial.java.threads;
public class TestThreads {
/**
* @param args
*/
public static void main(String[] args) {
CommonLock commonLock = new CommonLock();
Thread1 thread1 = new Thread1(commonLock);
Thread2 thread2 = new Thread2(commonLock);
thread1.start();
thread2.start();
}
}
/*
* Common monitor lock between both threads, used for communication using wait
* notify.
*/
class CommonLock {
}
// Extending Thread instead of Runnable as its just a test
class Thread1 extends Thread {
private CommonLock commonLock;
public Thread1(CommonLock commonLock) {
this.commonLock = commonLock;
}
public void run() {
System.out.println("Started thread 1");
System.out.println("waiting thread 1");
try {
// TO wait on commonLock, first need to get lock on commonLock. SO
// put synchronized block of commonLock.
synchronized (commonLock) {
commonLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("DONE waiting thread 1 as I got notification from THread 2");
}
}
class Thread2 extends Thread {
private CommonLock commonLock;
public Thread2(CommonLock commonLock) {
this.commonLock = commonLock;
}
public void run() {
System.out.println("Running thread 2");
try {
System.out.println("Sleeping thread 2");
// Just take gap of 2 sec before notifying.
Thread.sleep(2000);
// TO notify on commonLock, first need to get lock on commonLock. SO
// put synchronized block of commonLock.
synchronized (commonLock) {
System.out.println("Notifying thread 2");
commonLock.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}