Java 如何从多个线程获取数据?

Java 如何从多个线程获取数据?,java,multithreading,Java,Multithreading,我目前正在开发一个应用程序,通过IP网络远程监控一些对象。网络中的每个节点定期发送来自传感器的更新数据(电压、电流、温度等) 我启动一个新线程来处理每个远程对象。但是我在从线程传输数据时遇到了问题 将数据传输到主线程的最佳方式是什么?我应该使用我所拥有的还是其他东西?也许可以尝试将您的数据放入BlockingQueue并在主线程中获取数据 例如: public class Producer implements Runnable { //this class puts objects with

我目前正在开发一个应用程序,通过IP网络远程监控一些对象。网络中的每个节点定期发送来自传感器的更新数据(电压、电流、温度等)


我启动一个新线程来处理每个远程对象。但是我在从线程传输数据时遇到了问题


将数据传输到主线程的最佳方式是什么?我应该使用我所拥有的还是其他东西?

也许可以尝试将您的数据放入BlockingQueue并在主线程中获取数据

例如:

public class Producer implements Runnable { //this class puts objects with data into BlockingQueue

private BlockingQueue<Object> queue;

public Producer(BlockingQueue<Object> q) {
    this.queue = q;
}

@Override
public void run() {
    //place fot your instruction
    Object yourData = new Object();
    }

    try {
        queue.put(yourData);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
公共类生成器实现可运行的{//该类将包含数据的对象放入BlockingQueue
私有阻塞队列;
公共制作人(封锁队列q){
这个.queue=q;
}
@凌驾
公开募捐{
//服从你的指示
对象yourData=新对象();
}
试一试{
queue.put(您的数据);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
这是从BlockingQueue读取数据的类

public class Consumer implements Runnable{

private BlockingQueue<Object> queue;

public Consumer(BlockingQueue<Object> q){
    this.queue=q;
}

@Override
public void run() {
    try{
        Object date = queue.take()
        // your operations witha data

    }catch(InterruptedException e) {
        e.printStackTrace();
    }
}
公共类使用者实现可运行{
私有阻塞队列;
公共消费者(封锁队列q){
队列=q;
}
@凌驾
公开募捐{
试一试{
对象日期=queue.take()
//您的操作需要一个数据
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}


或者使用ExecutorService和Future类

解决此类问题的常见方法是将IO从处理中分离,因此在您的情况下,您将有一个线程从套接字读取数据并将数据传递给工作线程进行处理

套接字IO

从socket IO开始,自Java7以来,NIOAPI已经可用,这意味着您可以将防止阻塞主线程所需的线程留给操作系统

您可以侦听传入的连接,然后使用和开始阅读,如下所示:

AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
serverSocketChannel.accept(null, new AcceptAndReadHandler());
private class AcceptAndReadHandler implements CompletionHandler<AsynchronousSocketChannel,Void>
{
  public void completed(AsynchronousSocketChannel channel, Void attribute) 
  {
    serverSocketChannel.accept(null, this);

    ReadHandler readHandler = new ReadHandler(channel);
    channel.read(readHandler.getBuffer(), Void, readHandler)
  }   
}

public class ReadHandler implements CompletionHandler<Integer,Void>
{
  private ByteBuffer buffer;

  public ReadHandler(AsynchronousSocketChannel channel)
  {
    this.channel = channel;
    this.buffer = ByteBuffer.allocate(1024);
  }

  public ByteBuffer getBuffer() { return this.buffer; }

  public void completed(Integer read, Void attribute) 
  {
    byte[] data = new byte[read];
    buffer.get(data);  

    ...

    ReadHandler readHandler = new ReadHandler(channel);  
    channel.read(readHandler.getBuffer(), Void, readHandler).
  }
}
public static void main(String[] args)
{
  boolean running = true;
  Runtime.getRuntime().addShutdownHook(() -> running = false);

  Executor executor = Executors.newFixedThreadPool(10); 

  AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
serverSocketChannel.accept(null, new AcceptAndReadHandler(executor));

  while (running)
  {
    ...
  }      
}
其中s看起来像这样:

AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
serverSocketChannel.accept(null, new AcceptAndReadHandler());
private class AcceptAndReadHandler implements CompletionHandler<AsynchronousSocketChannel,Void>
{
  public void completed(AsynchronousSocketChannel channel, Void attribute) 
  {
    serverSocketChannel.accept(null, this);

    ReadHandler readHandler = new ReadHandler(channel);
    channel.read(readHandler.getBuffer(), Void, readHandler)
  }   
}

public class ReadHandler implements CompletionHandler<Integer,Void>
{
  private ByteBuffer buffer;

  public ReadHandler(AsynchronousSocketChannel channel)
  {
    this.channel = channel;
    this.buffer = ByteBuffer.allocate(1024);
  }

  public ByteBuffer getBuffer() { return this.buffer; }

  public void completed(Integer read, Void attribute) 
  {
    byte[] data = new byte[read];
    buffer.get(data);  

    ...

    ReadHandler readHandler = new ReadHandler(channel);  
    channel.read(readHandler.getBuffer(), Void, readHandler).
  }
}
public static void main(String[] args)
{
  boolean running = true;
  Runtime.getRuntime().addShutdownHook(() -> running = false);

  Executor executor = Executors.newFixedThreadPool(10); 

  AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
serverSocketChannel.accept(null, new AcceptAndReadHandler(executor));

  while (running)
  {
    ...
  }      
}
为此,您需要修改s以通过
队列
,以便
ReadHandler
可以将
数据
添加到队列中

如果要对处理执行多线程操作,则应使用,如下所示:

AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
serverSocketChannel.accept(null, new AcceptAndReadHandler());
private class AcceptAndReadHandler implements CompletionHandler<AsynchronousSocketChannel,Void>
{
  public void completed(AsynchronousSocketChannel channel, Void attribute) 
  {
    serverSocketChannel.accept(null, this);

    ReadHandler readHandler = new ReadHandler(channel);
    channel.read(readHandler.getBuffer(), Void, readHandler)
  }   
}

public class ReadHandler implements CompletionHandler<Integer,Void>
{
  private ByteBuffer buffer;

  public ReadHandler(AsynchronousSocketChannel channel)
  {
    this.channel = channel;
    this.buffer = ByteBuffer.allocate(1024);
  }

  public ByteBuffer getBuffer() { return this.buffer; }

  public void completed(Integer read, Void attribute) 
  {
    byte[] data = new byte[read];
    buffer.get(data);  

    ...

    ReadHandler readHandler = new ReadHandler(channel);  
    channel.read(readHandler.getBuffer(), Void, readHandler).
  }
}
public static void main(String[] args)
{
  boolean running = true;
  Runtime.getRuntime().addShutdownHook(() -> running = false);

  Executor executor = Executors.newFixedThreadPool(10); 

  AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
serverSocketChannel.accept(null, new AcceptAndReadHandler(executor));

  while (running)
  {
    ...
  }      
}
同样,您需要修改s,这一次您可以将
ReadHandler
executor
传递给提交处理逻辑


这两种方法之间的重要区别在于,对于多线程示例,无法保证处理顺序。

如果您发布一些代码“但是我在从踏板传输数据方面有问题”,那么回答您的问题可能会更容易。“有什么问题吗?”我应该使用我拥有的吗,你们有什么?你们听说过未来物体的服务和用途吗?我试着理解你们的问题。我认为您需要使用共享资源,让所有线程将它们的数据放在其中,并且主线程可以并行地访问它。类似java.util.concurrent.ConcurrentMap的内容