java调用dll动态库多线程数据不对(java调用dll动态库多线程数据不对怎么办)

java调用dll动态库多线程数据不对(java调用dll动态库多线程数据不对怎么办)一 条件变量 条件变量实现了 java util concurrent locks Condition 接口 条件变量的实例化就是通过一个 Lock 对象上调用 newCondition 方法获得的 这样条件就和一个锁绑定起来了 因此 Java 中的条件变量只能和锁配合使用 来控制并发程序访问竞争资源的安全 条件变量的出现是为了更精细的控制线程等待与唤醒 一个锁可以有多个条件 每个条件上有多个线程等待 通过 await 方法 可以让线程在该条件下等待 当调用 signalAll 方法时



一、条件变量

  条件变量实现了java.util.concurrent.locks.Condition接口,条件变量的实例化就是通过一个Lock对象上调用newCondition()方法获得的,这样条件就和一个锁绑定起来了。因此,Java中的条件变量只能和锁配合使用,来控制并发程序访问竞争资源的安全。

  条件变量的出现是为了更精细的控制线程等待与唤醒,一个锁可以有多个条件,每个条件上有多个线程等待,通过await()方法,可以让线程在该条件下等待。当调用signalAll()方法时,又可以唤醒该条件下等待的线程。条件变量比较抽象,原因是它不是自然语言中的条件概念,而是控制程序的一种手段。

  看个例子,有一个账户,多个用户(线程)在同时操作这个账户,有的存款有的取款,存款随便存,但取款有限制,不能透支,任何试图透支的操作都将等待里面有足够的存款时才执行操作。

  CaseTest.java

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  结果为:

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  如果不用条件变量和锁,如何实现此功能呢?

CaseTest.java

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  第二种方式是用同步方法的第一种方法,以前说过这种方法不如第二种好,下面改进一下该同步的程序:

CaseTest.java

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

二、Volatile变量

  具体的内容,详见 JAVA理论与实践:正确使用Volatile变量

三、原子量

  所谓原子量就是操作变量的操作是“原子的”,该操作不可再分,因此线程是安全的。volatile、synchronized关键字来解决并发访问的安全问题,但这样太麻烦。有一个用来进行单变量多线程并发安全访问的工具包java.util.concurrent.atmoic。

  Test.java

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  结果为

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  这个例子是个反例,可见到虽然使用了原子量,但是并发访问还是有问题,那么问题在哪?原子量虽然可以保证单个变量在某一个操作过程安全,但无法保证整个代码块,或者说整个程序的安全。因此,通常可以使用锁等同步机制控制整个程序的安全性。

  Test.java

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  结果为:

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

此时,加入了一个对象锁,来控制并发访问的控制,不管程序运行多少次,结果都是一样的。有关原子的用法仅仅保证变量操作的原子性,但是需要考虑整个过程的线程安全性。

四、信号量

  一个信号量管理很多的许可证,为了获取信号量,线程通过调用acquire请求许可。Java信号量实际上是一个功能完毕的计数器,并由此限制了通过的线程数量,其他线程可以通过调用release释放许可。

  它对控制一定资源的消费与回收有着重要意义,信号量常常用于多线程的代码中,并能监控有多少数目的线程等待获取资源,并且通过信号量可以得知可用资源的数目等等,这里强调数目二字,并不是指有哪些在等待,哪些资源可用。例子:

SignalTest.java

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  结果为:

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  信号量仅仅是对池资源进行监控,但不能 保证线程的安全,因此,应该自己控制线程的安全访问资源。

五、线程池

  线程池的思想还是一种对象池的思想,开辟一块内存空间,里面存放众多的(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完线程对象归池,这样可以避免反复创建线程对象带来的性能开销,节约系统资源。

   线程池分为固定尺寸的线程池、可变尺寸线程池。

1、固定大小的线程池

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

2、单任务线程池

  在上一例修改一行pool对象的代码为:

  以上两种情况都是大小固定的,当要加入的池的线程(或任务)超过池最大尺寸的时候,则入此线程池需要排队等待。

3、可变尺寸的线程池

4、延迟线程池

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

5、单任务延迟线程池

  在4的代码基础上修改为:

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

6、自定义线程池

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

  创建自定义线程池的构造方法很多,本例中的含义如下:

  虽然自定义线程池麻烦点,但是可以获取当前线程池的尺寸、正在执行任务的线程数、工作队列等。

六、障碍器

  当计算一个大的任务时,常常需要分配好多子任务去执行,只有当所有子任务执行完时,才能执行主任务,这时候需要借助障碍器。

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

java多线程同时修改共享变量会出错吗_java

java多线程同时修改共享变量会出错吗_System_02

View Code

当神已无能为力,那便是魔渡众生



编程小号
上一篇 2025-03-26 12:30
下一篇 2025-02-15 11:06

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/40321.html