Tag: 并发

避免同一缓存区域的多次重新填充(由于并发)

我有一个高流量的网站,我使用hibernate。 我还使用ehcache来缓存生成页面所需的一些实体和查询。 问题是“并行缓存未命中”,长期解释是,当应用程序启动并且缓存区域很冷时,每个缓存区域被不同的线程多次填充(而不是仅一次),因为该站点被许多用户击中同时。 此外,当某些缓存区域无效时,由于相同的原因,它会被重新填充多次。 我怎么能避免这个? 我设法通过向hibernate.cache.provider_class提供我自己的实现, 将1个实体和1个查询缓存转换为BlockingCache ,但BlockingCache的语义似乎不起作用。 甚至有时甚至最糟糕的是BlockingCache死锁(块)并且应用程序完全挂起。 线程转储显示在get操作上阻止BlockingCache的互斥锁处理。 那么,问题是,Hibernate是否支持这种用途? 如果没有,你如何在生产中解决这个问题? 编辑 : hibernate.cache.provider_class指向我的自定义缓存提供程序,它是SingletonEhCacheProvider的复制粘贴和start()方法的结尾(在第136行之后)我这样做: Ehcache cache = manager.getEhcache(“foo”); if (!(cache instanceof BlockingCache)) { manager.replaceCacheWithDecoratedCache(cache, new BlockingCache(cache)); } 这样在初始化时,在其他人触摸名为“foo”的缓存之前,我用BlockingCache来装饰它。 “foo”是查询缓存,“bar”(相同的代码但省略)是pojo的实体缓存。 编辑2 :“似乎不起作用”意味着最初的问题仍然存在。 由于并发性,缓存“foo”仍然使用相同的数据重新填充多次。 我通过使用10个线程的JMeter强调网站来validation这一点。 我希望9个线程阻塞,直到第一个请求“foo”数据完成它的工作(执行查询,在缓存中存储数据),然后直接从缓存中获取数据。 编辑3 :这个问题的另一个解释可以在https://forum.hibernate.org/viewtopic.php?f=1&t=964391&start=0看到,但没有明确的答案。

封闭对象的引用通过匿名类java转义

我在实践中阅读Java并发性,下面的例子来自于此。 我的问题是这个参考逃脱是什么意思? 会有什么问题? 。 该引用如何从doSomething(e)中逃脱。 public class ThisEscape { public ThisEscape(EventSource source) { source.registerListener( new EventListener() { public void onEvent(Event e) { doSomething(e); } } ); } } 这是如何解决这个问题的 public class SafeListener { private final EventListener listener; private SafeListener() { listener = new EventListener() { public void onEvent(Event e) { doSomething(e); } }; } public […]

以线程安全方式创建对象

直接来自这个网站,我遇到了关于创建对象线程安全性的以下描述。 警告:构造将在线程之间共享的对象时,要非常小心,对对象的引用不会过早“泄漏”。 例如,假设您要维护一个包含每个类实例的List调用实例。 您可能想要将以下行添加到构造函数中: instances.add(本); 但是其他线程可以在构造对象完成之前使用实例来访问对象。 是否有人能够用其他词语或其他更可抓住的例子来表达相同的概念? 提前致谢。

wait-notify和CountDownLatch之间的区别

我需要一些帮助来理解使用CountDownLatch优于传统的wait-notify的优点。 我认为notifyAll()确实做了同样的事情,它似乎更容易使用(也许是因为熟悉)。 另外,来自CountDownLatch的wait()和await()有什么区别? 谢谢 ! 编辑:我想我需要改写我的查询: Await()根据文档说: 除非线程被中断,否则导致当前线程等待锁存器倒计数到零。 对我来说很难看出wait()和await()之间的区别 – await()确实在封面下使用了wait(),而且当count到零时似乎有一个隐式的notifyAll()。 我要问的是,为什么我不应该只使用wait-notifyAll()机制(使用我自己的计数器变量处理),而不是使用CountDownLatch?

并行运行多个JPA事务

我有两个(或更多)Java线程使用JPA从mysql数据库创建,更新和删除实体。 为了实现这一点,我有一个PersistenceLayer类创建EntityManager并为我的所有实体提供保存,更新和删除方法,如下所示: public void saveEntity(Entity entity) { manager.getTransaction().begin(); manager.persist(entity); manager.getTransaction().commit(); } public void saveEntity2(Entity2 entity) { manager.getTransaction().begin(); manager.persist(entity); manager.getTransaction().commit(); } 如果一个线程同时进入操作saveEntity和另一个saveEntity2,两者都将尝试从EntityManager获取事务,这将失败。 但是我一直认为底层数据库能够管理多个事务,特别是如果两个事务处理不同的行甚至不同的表。 当然,我可以同步块,但这意味着一次只能进行一次数据库连接,这种连接不会扩展到创建多个线程的多个用户。 我在这做什么错误的假设? 是否可以通过JPA向数据库提交多个事务并让数据库处理并发问题?

等待多个期货的回调

最近我使用API​​深入研究了一些工作。 API使用Unirest http库来简化从Web接收的工作。 当然,由于从API服务器调用数据,我试图通过使用API​​的异步调用来提高效率。 我的想法结构如下: 通过返回期货结果来创建数据数组 显示数据+从数据中收集的其他信息 因此,在开始第二步之前,我需要返回所有数据。 我的代码如下: Future < HttpResponse > future1 = Unirest.get(“https://example.com/api”).asJsonAsync(new Callback () { public void failed(UnirestException e) { System.out.println(“The request has failed”); } public void completed(HttpResponse response) { System.out.println(response.getBody().toString()); responses.put(response); } public void cancelled() { System.out.println(“The request has been cancelled”); } }); Future < HttpResponse > future2 = Unirest.get(“https://example.com/api”).asJsonAsync(new […]

对于ReentrantLock,实际使用lockInterruptibly

你实际上对这个方法使用了什么lockInterruptibly ? 我已阅读API,但对我来说不是很清楚。 换句话说,有人可以表达吗?

Java为高并发情况限制了非阻塞缓冲区

基本上我需要一个数据结构来存储服务器端的临时聊天消息。 它应该是: 有界:因为我不需要存储太多消息,客户端将每秒发送请求以获取新消息。 我认为绑定的大小应该是最大值。 在一秒钟内挂载并发请求。 当缓冲区已满时,将删除旧消息。 适合高并发访问:我不想使用像Collections.synchronizedXXXX这样的数据结构,因为在迭代期间,如果其他线程更改了数据结构,例如添加了一条消息,它将抛出exception,所以我必须锁定整个数据结构,实际上我并不关心客户端请求是否可以获得最后插入的消息,因为它们将在一秒后发送新请求,另一方面写操作应该永远不会延迟。 包java.util.concurrency下的类似乎是解决方案,但是…… 非阻塞:LinkedBlockingQueue,ArrayBlockingQueue它们可以是有界的,并且在迭代期间不会抛出exception,但它们都是阻塞队列。 当队列已满时,我想将新元素添加到尾部并从头部删除旧元素而不是阻塞它,并等待某人删除标题。 所以我的问题是第三个库有什么好的实现吗? 比如谷歌番石榴? 或者您可能更了解在服务器上存储临时聊天消息? 非常感谢你!

适用于Java的数据流编程API?

我正在寻找一个Java的数据流/并发编程API。 我知道有DataRush ,但它不是免费的。 我特别感兴趣的是多核数据处理,而不是分布式的,它排除了MapReduce或Hadoop 。 有什么想法吗? 谢谢,罗洛

单线程处理任务而不排队进一步的请求

我要求异步执行任务,同时丢弃任何进一步的请求,直到任务完成。 同步方法只是将任务排队,不会跳过。 我最初想过使用SingleThreadExecutor,但也会排队任务。 然后我查看了ThreadPoolExecutor,但是它读取队列以获取要执行的任务,因此将执行一个任务并且至少有一个任务排队(其他任务可以使用ThreadPoolExecutor.DiscardPolicy丢弃)。 我唯一能想到的是使用信号量来阻止队列。 我来自以下示例来展示我正在努力实现的目标。 有更简单的方法吗? 我错过了一些明显的东西吗 import java.util.concurrent.*; public class ThreadPoolTester { private static ExecutorService executor = Executors.newSingleThreadExecutor(); private static Semaphore processEntry = new Semaphore(1); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 20; i++) { kickOffEntry(i); Thread.sleep(200); } executor.shutdown(); } private static void kickOffEntry(final int […]