【发布时间】:2015-11-30 16:56:49
【问题描述】:
所以我的多线程部分工作。当我在编译后第一次运行我的程序时,它只运行 3 个线程中的 1 个或 2 个。然后立即再次运行它,它在所有线程都激活并运行的情况下运行得非常好。我想不出为什么所有线程都不会在第一次执行 java 类时运行,然后在第一次执行终止后开始执行该类的第二次执行。
我在 Raspberry Pi 2 上使用 Pi4j。我需要代码第一次运行良好,因为我试图在 Pi 启动时运行它。
这是我开始线程的地方。
public class Doors {
public static void main(String[] args) {
Thread door1 = new Thread(new DoorSwitch(0));
door1.start();
Thread door2 = new Thread(new DoorSwitch(1));
door2.start();
Thread door3 = new Thread(new DoorSwitch(2));
door3.start();
}
这就是线程正在运行的内容。线程正在传递我称之为门的值。
public class DoorSwitch implements Runnable{
int p;
int doorID;
int tempPin;
static DBConnection db = new DBConnection();//create a new object of database connection class
public DoorSwitch(int currPin){
p = currPin;
doorID = (p + 1);
}
public void run()
{
try{
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalInput[] gpPins = {
gpio.provisionDigitalInputPin(RaspiPin.GPIO_28, PinPullResistance.PULL_UP),
gpio.provisionDigitalInputPin(RaspiPin.GPIO_29, PinPullResistance.PULL_UP),
gpio.provisionDigitalInputPin(RaspiPin.GPIO_27, PinPullResistance.PULL_UP),
};
for (int i=1; i<gpPins.length; i++){
if(p == i){
tempPin = p;
}
}
final GpioPinDigitalInput door = gpPins[tempPin];
door.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
if(event.getState() == PinState.HIGH){
try{
db.dbConnection();
System.out.println(doorID);
System.out.println("Door Open! " + p);
String update = "UPDATE `door` SET `status`=" + 1 + " WHERE `id`="+ doorID +";";
db.getStatement().executeUpdate(update);
String log = "INSERT INTO `door_log` (`door_id`, `status`) VALUES ("+ doorID + ",1);";
db.getStatement().executeUpdate(log);
} catch (SQLException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(event.getState() == PinState.LOW){
try{
db.dbConnection();
System.out.println(doorID);
System.out.println(" Door Closed! " + p);
String update = "UPDATE `door` SET `status`=" + 0 + " WHERE `id`="+ doorID +";";
db.getStatement().executeUpdate(update);
String log = "INSERT INTO `door_log` (`door_id`, `status`) VALUES ("+ doorID + ",0);";
db.getStatement().executeUpdate(log);
} catch (SQLException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
while(true) {
Thread.sleep(500);
}
// stop all GPIO activity/threads by shutting down the GPIO controller
// (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
// gpio.shutdown(); <--- implement this method call if you wish to terminate the Pi4J GPIO controller
}catch(Exception e){
}
}
任何帮助将不胜感激。 谢谢
【问题讨论】:
-
你说,“...它只运行 3 个线程中的 1 个或 2 个。”你怎么知道的?这段代码应该做什么?它实际上在做什么?到目前为止,您尝试过做什么来查明问题?
-
你的线程除了注册一个事件处理程序之外什么都不做,然后
while(true) sleep(500);你为什么要使用一个线程呢? -
您正在使用
for循环来测试p是否在[0..2] 范围内。你不需要为此使用循环。 -
我正在使用多线程来运行 3 个不同的磁门传感器,这样我就不必为每个传感器运行 3 个单独的类。这样,我有 1 个主类并运行 3 次,每次运行时调用不同的 gpio 端口。通过激活传感器然后检查数据库以查看是否记录了日志,我知道它何时起作用和不起作用。但是当我重新启动后第一次运行它时,所有线程都没有被激活。
-
除了调用
door.addListener(...),您的线程似乎没有做任何事情,然后永远休眠。为什么不让主线程添加监听器?永远沉睡的线程有什么用?
标签: java multithreading raspberry-pi2