有3个线程正在运行...仅从最后一个线程接收信息....线程中的新线程

时间:2018-08-09 19:47:47

标签: java multithreading

我有3个RFID阅读器,正在阅读RFID标签。我正在运行这些,但是由于某种原因,我仅从正在处理的最后一个reader(thread)接收信息。我想念什么?阅读器位于包含ipaddress,用户名,端口,密码的数组中。我可以为所有人收听同一服务吗?我是线程的新手。........TagInventory是所有这些都位于的类的名称。

代码如下:

private void Start() throws AlienReaderException, IOException{
    ThreadStop = false;

     service= new MessageListenerService(3900);
     service.setMessageListener(this);
     service.startService();
    System.out.println("length of readers: "+Reader.ipAddress.length);

      for (lastThreadId = 0; lastThreadId < Reader.ipAddress.length; lastThreadId++)
      {
          m_inventory[lastThreadId] = new AlienReader(Reader.ipAddress[lastThreadId], Reader.port, Reader.username[lastThreadId], Reader.password[lastThreadId]);
          log.info("taginventory reader: "+ Reader.ipAddress[lastThreadId]+"Thread: "+lastThreadId);
          m_run_process[lastThreadId] = new Thread(new StartInventoryThread(Reader.ipAddress[lastThreadId], Reader.port, Reader.username[lastThreadId], Reader.password[lastThreadId], m_inventory[lastThreadId]));
          m_run_process[lastThreadId].start();
      }
      --lastThreadId;

      try
      {
         // Thread.sleep(1000);
          Thread.sleep(2000);
      }
      catch (Exception ex)
      {
          ex.getMessage();
      }


}

class StartInventoryThread implements Runnable{

    private String ip;
    private int port;
    private String user;
    private String pwd;
    private AlienReader ar;


    StartInventoryThread(String ip, int port, String user, String pwd, AlienReader ar){
        this.ip=ip;
        this.port=port;
        this.user=user;
        this.pwd=pwd;
        this.ar=ar;
    }


    @Override
    public void run() {
        try {
            while(!stopInventory){
                startRead(ip,port,user,pwd);

            }
        } catch (AlienReaderException | InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

public void startRead(String ip, int port, String user, String password) throws AlienReaderException, InterruptedException, UnknownHostException{
    String myIP=InetAddress.getLocalHost().getHostAddress();
    //System.out.println("ip"+ ip);
    AlienReader ar= new AlienReader(ip, port, user, password);
    ar.open();
     //log.info("Reader" + ar.getIPAddress());

    ar.setNotifyAddress(myIP, 3900);
    ar.setNotifyFormat(AlienClass1Reader.TEXT_FORMAT);
    //ar.setNotifyTrigger("TrueFalse");
    ar.setNotifyTrigger("Add");
    ar.setNotifyMode(AlienClass1Reader.ON);
    // log.info("MessageListenerService has started for reader: " + ip);

    //complete process in here
    ar.autoModeReset();
    ar.setAutoStopTimer(5000); // Read for 5 seconds
    ar.setAutoMode(AlienClass1Reader.ON);
    tagTable.setTagTableListener(tagTableListener);
    tagTable.setPersistTime(3600);

    //tagTable.setPersistTime(1800000);
    ar.close();

    long runTime = 10000; // milliseconds
     long startTime = System.currentTimeMillis();
     do {
     Thread.sleep(1000);
     } while(service.isRunning()
     && (System.currentTimeMillis()-startTime) < runTime);

     // Reconnect to the reader and turn off AutoMode and TagStreamMode.
    // log.info("\nResetting Reader");
    ar.open();
    ar.autoModeReset();
    ar.setNotifyMode(AlienClass1Reader.OFF);
    ar.close();

}

public static void main(String args[]){

      Thread thr=new Thread(new Runnable(){
          @Override
          public void run(){
              try {
                new TagInventory();
            } catch (AlienReaderException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
          }
      });
  thr.start();
}

1 个答案:

答案 0 :(得分:0)

概述

在整个代码中,我发现您的逻辑中存在许多问题和潜在危害。我将逐一介绍并指导您解决与这些问题相适应的相应概念。

主要

在您的main(String args[])中,添加一个join()调用,以便调用线程(可能是主线程)可以等到Thread thr完成之后再退出。

public static void main(String args[]){

      Thread thr=new Thread(new Runnable(){
          @Override
          public void run(){
              try {
                new TagInventory();
            } catch (AlienReaderException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
          }
      });
  thr.start();
  thr.join();
}

开始

假设您期望线程在Start()函数完成之前完成,我将解释如何获得该功能。不要使用Thread.sleep(),因为它被认为是不好的编程。而是使用join()函数。强制调用线程等待或 block 直到该线程完成。下面添加的逻辑将循环遍历m_run_process block 直到完成。如果您要确保其他位置都可以完成,则可以将for-loop放在此处。

private void Start() throws AlienReaderException, IOException{
    ThreadStop = false;

    service= new MessageListenerService(3900);
    service.setMessageListener(this);
    service.startService();
    System.out.println("length of readers: "+Reader.ipAddress.length);

    for (lastThreadId = 0; lastThreadId < Reader.ipAddress.length; lastThreadId++)
    {
        m_inventory[lastThreadId] = new AlienReader(Reader.ipAddress[lastThreadId], Reader.port, Reader.username[lastThreadId], Reader.password[lastThreadId]);
        log.info("taginventory reader: "+ Reader.ipAddress[lastThreadId]+"Thread: "+lastThreadId);
        m_run_process[lastThreadId] = new Thread(new StartInventoryThread(Reader.ipAddress[lastThreadId], Reader.port, Reader.username[lastThreadId], Reader.password[lastThreadId], m_inventory[lastThreadId]));
        m_run_process[lastThreadId].start();
    }
    --lastThreadId;

    for(Thread inventoryThread : m_run_process)
        inventoryThread.join()
}

开始阅读

在这里访问非线程安全的对象和变量似乎有很多问题; servicestopInventorytagTable(我没有看到完整的文件,我正在做假设,并且在任何地方都看不到同步)。现在,建议您阅读 Java内存模型 Java内存屏障原子操作同步,< strong>线程安全和 JVM 。本质上,您的逻辑可能会导致数据和/或线程被覆盖,从而看到不同的 cache 值。要进行纠正,您必须通过同步和原子性使共享的可变实例成为线程安全的。

public void startRead(String ip, int port, String user, String password) throws AlienReaderException, InterruptedException, UnknownHostException{
    String myIP=InetAddress.getLocalHost().getHostAddress();
    //System.out.println("ip"+ ip);
    AlienReader ar= new AlienReader(ip, port, user, password);
    ar.open();
     //log.info("Reader" + ar.getIPAddress());

    ar.setNotifyAddress(myIP, 3900);
    ar.setNotifyFormat(AlienClass1Reader.TEXT_FORMAT);
    //ar.setNotifyTrigger("TrueFalse");
    ar.setNotifyTrigger("Add");
    ar.setNotifyMode(AlienClass1Reader.ON);
    // log.info("MessageListenerService has started for reader: " + ip);

    //complete process in here
    ar.autoModeReset();
    ar.setAutoStopTimer(5000); // Read for 5 seconds
    ar.setAutoMode(AlienClass1Reader.ON);
    tagTable.setTagTableListener(tagTableListener);
    tagTable.setPersistTime(3600);

    //tagTable.setPersistTime(1800000);
    ar.close();

    long runTime = 10000; // milliseconds
     long startTime = System.currentTimeMillis();
     do {
     Thread.sleep(1000);
     } while(service.isRunning()
     && (System.currentTimeMillis()-startTime) < runTime);

     // Reconnect to the reader and turn off AutoMode and TagStreamMode.
    // log.info("\nResetting Reader");
    ar.open();
    ar.autoModeReset();
    ar.setNotifyMode(AlienClass1Reader.OFF);
    ar.close();

}