所以我的多线程部分工作。当我编译后第一次运行程序时,它只运行 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){
}
}
任何帮助将不胜感激。 谢谢
最佳答案
检查db:共享,使用时不 protected ,并且在每个线程中创建。
结果可能是不可预测的。
我建议:
1 添加此
static final Object db_sync=new Object();
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 db的使用
synchronized(db_sync)
{
// Do what you want with db
}
关于Java、多线程和 Raspberry Pi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33980484/