简体   繁体   English

Java,多线程和Raspberry Pi

[英]Java, MultiThreading, and Raspberry Pi

So I have my multi threading partially working. 所以我的多线程部分工作。 When I run my program the very first time after compiling it only runs 1 or 2 of the 3 threads. 当我在编译后第一次运行程序时,它仅运行3个线程中的1个或2个。 Then running it again right after, it runs perfectly fine with all of the threads activated and running. 然后立即再次运行它,它在所有线程被激活并运行的情况下运行得非常好。 I can't think of any reason why all of the threads would not run on the first execution of the java class, and then start working on the second execution of the class after the first one has been terminated. 我想不出任何原因为什么所有线程都不会在java类的第一次执行时运行,然后在第一个类终止后才开始在该类的第二次执行上工作。

I am using Pi4j on a Raspberry Pi 2. I need the code to run fine the first time because I am trying to run this on bootup of the Pi. 我在Raspberry Pi 2上使用Pi4j。我第一次需要代码才能正常运行,因为我试图在Pi的启动时运行它。

This is where I start the threading. 这是我开始线程化的地方。

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();
}

This is what the Thread is running. 这就是线程正在运行的东西。 The threading is passing in the value of what I call the door. 线程传递了我所说的门的值。

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){

    }

}

Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks 谢谢

check db: shared, not protected when used, and created in each thread. 检查数据库:共享,在使用时不受保护,并在每个线程中创建。

The result can be unpredictable. 结果可能无法预测。

I propose: 我提议:

1 Add this 1添加

 static final Object db_sync=new Object();

2 Initialize db only once, and call it in the constructor of DoorSwitch 2仅初始化一次db,然后在DoorSwitch的构造函数中调用它

static DBConnection db=null;

static db_initialize()
{

synchronized(db_sync)
 {
 if (db==null) 
    db = new DBConnection();//create a new object of database connection class
  }

}

3 Surround the use of db 3环绕声使用db

synchronized(db_sync)
 {
  // Do what you want with db
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM