当前位置:网站首页 > 数据科学与大数据 > 正文

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



一、条件变量

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

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

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

  CaseTest.java

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

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

  结果为:

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

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

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

CaseTest.java

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

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

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

CaseTest.java

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

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

二、Volatile变量

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

三、原子量

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

  Test.java

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

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

  结果为

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

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

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

  Test.java

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

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

  结果为:

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

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

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

四、信号量

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

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

SignalTest.java

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

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

  结果为:

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

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

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

五、线程池

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

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

1、固定大小的线程池

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

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

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

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

2、单任务线程池

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

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

3、可变尺寸的线程池

4、延迟线程池

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

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

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

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

5、单任务延迟线程池

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

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

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

6、自定义线程池

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

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

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

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

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

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

六、障碍器

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

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

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

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

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

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

到此这篇java调用dll动态库多线程数据不对(java调用dll动态库多线程数据不对怎么办)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • list转字符串数组(list数据转字符串)2025-02-18 15:45:09
  • 数据库要怎么学(数据库怎么学精)2025-02-18 15:45:09
  • 天气预报数据接口(天气预报 接口)2025-02-18 15:45:09
  • impdp导入表数据命令(impdp导入表空间)2025-02-18 15:45:09
  • 3DTiles数据转shp(3dtiles数据下载)2025-02-18 15:45:09
  • 安卓系统卸载的软件怎么找回数据(安卓系统卸载的软件怎么找回数据啊)2025-02-18 15:45:09
  • jdbc连接数据库步骤代码(jdbc连接数据库的几种方法)2025-02-18 15:45:09
  • 数据库端口号怎么查看(数据库端口号怎么查看的)2025-02-18 15:45:09
  • 数据库入门知识(数据库入门知识点)2025-02-18 15:45:09
  • 数据库怎么创建dblink(数据库怎么创建用户)2025-02-18 15:45:09
  • 全屏图片