java通过snmp多线程并发访问设备获取数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java通过snmp多线程并发访问设备获取数据相关的知识,希望对你有一定的参考价值。

请问,java通过snmp多线程并发获取多个设备的数据,该怎样做比较好?目前做法是通过继承Runnable,然后new出多个对象去访问设备,然后又join每个对象。获取到的数据先加入一个list中,等全部获取完后再显示出来,可有时会有一些设备数据漏掉。请问该怎样解决?
如果不用join的话,程序会还没等待线程返回就执行线程以后的代码。加入list时锁了,可是还是会有一些数据丢失。snmp访问设备都是UDP报文,会不会因为报文超时造成的呢?有什么更好的办法来实现呢?

参考技术A snmp访问设备获取数据有异步的方法,跟多线程同时使用效果更好 参考技术B 不需要join。

同一个 list, 添加内容时 锁一下追问

你好,请看看我补充的问题。谢谢了!

参考技术C 我给你发到你的邮箱里。追问

哥们,太感谢了,能否上传附件给我呀?

参考技术D 如果你使用JDK7,你可以看一下ForkJoinPool或者Phaser

Java核心-多线程-并发控制器-Semaphore信号量

  1. Semaphore是非常有用的一个多线程并发控制组件(Java还有CountDownLatch、CyclicBarrier、Exchanger多线程组件),它相当于是一个并发控制器,是用于管理信号量的。构造的时候传入可供管理的信号量的数值,这个数值就是控制并发数量的,就是同时能几个线程访问。我们需要控制并发的代码,执行前先通过acquire方法获取信号,执行后通过release归还信号 。每次acquire返回成功后,Semaphore可用的信号量就会减少一个,如果没有可用的信号,acquire调用就会阻塞,等待有release调用释放信号后,acquire才会得到信号并返回。
    private Semaphore semaphore = new Semaphore(3, true); #true时,使用公平策略,也就是是使用公平锁
    ps:注意这里信号量acquire方法和release方法是可以有参数的,表示获取/返还的信号量个数,如果不指定就是默认单个释放。

  2. Semaphore分为单值和多值两种
    • 单值的Semaphore管理的信号量只有1个,该信号量只能被1个,只能被一个线程所获得,意味着并发的代码只能被一个线程运行,这就相当于是一个互斥锁了。
    • 多值的Semaphore管理的信号量多余1个,主要用于控制并发数。
  3. 这种通过Semaphore控制并发并发数的方式和通过控制线程数来控制并发数的方式相比,粒度更小,因为Semaphore可以通过acquire方法和release方法来控制代码块的并发数。

  4. 在构造Semaphore对象时,同时可以控制并发时抢占锁的公平策略。在公平的锁上,线程按照他们发出请求的顺序获取锁,但在非公平锁上,则允许‘插队’:当一个线程请求非公平锁时,如果在发出请求的同时该锁变成可用状态,那么这个线程会跳过队列中所有的等待线程而获得锁。

  5. 非公平锁的效率高于公平锁,主要原因是,在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。
    ps.当持有锁的时间相对较长,应该使用公平锁。在这些情况下,插队带来的吞吐量提升可能不会出现。

  6. 使用示例,模仿上厕所排队的例子

 package common_test;
import java.util.Random;
import java.util.concurrent.*;

public class SemaphoreTest {
    
    private Semaphore semaphore = new Semaphore(3, true);
    private Random random = new Random();

    
    class Task implements Runnable{
        private String id;
        public Task(String id){
            this.id = id;
        }
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("茅坑" + id + " 被占用了");
                work();
                System.out.println("茅坑" + id + " 空了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                semaphore.release();
            }
        }
        
        public void work(){
            int worktime = random.nextInt(1000);
                    System.out.println("茅坑  " + id + "使用了"+ worktime + "秒");
            try {
                Thread.sleep(worktime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
            SemaphoreTest semaphoreTest = new SemaphoreTest();
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            newCachedThreadPool.submit(semaphoreTest.new Task(1+""));
            newCachedThreadPool.submit(semaphoreTest.new Task(2+""));
            newCachedThreadPool.submit(semaphoreTest.new Task(3+""));
            newCachedThreadPool.submit(semaphoreTest.new Task(4+""));
            newCachedThreadPool.submit(semaphoreTest.new Task(5+""));
            newCachedThreadPool.submit(semaphoreTest.new Task(6+""));
            newCachedThreadPool.submit(semaphoreTest.new Task(7+""));
            newCachedThreadPool.shutdown();
        }
}

以上是关于java通过snmp多线程并发访问设备获取数据的主要内容,如果未能解决你的问题,请参考以下文章

线程同步和并发

Java总结——通过Callable接口实现多线程,生产者消费者问题,多线下载(复制)文件

java 多线程问题 真的提高了效率吗?

怎么实现springMVC 多线程并发

线程概念及多线程控制

Java多线程—— synchronized关键字续