标签: java.util.concurrent

concurrentHashMap的片段用于检索对象或在缺少时创建它(作为原子操作)

在Java中,我想做这样的事情:

   Object r = map.get(t);
   if (r == null) {
      r = create(); // creating r is an expensive operation.
      map.put(t, r);  
   }
Run Code Online (Sandbox Code Playgroud)

现在,代码片段可以在多线程环境中执行. map可以是ConcurrentHashMap.

但是我如何使逻辑成为原子?

请不要像"同步"块那样给我一些简单的解决方案.我希望这个问题可以一劳永逸地解决.

java java.util.concurrent concurrent-programming

2
推荐指数
1
解决办法
1679
查看次数

为什么ConcurrentHashMap中的HashEntry是最终的?

我正在浏览ConcurrentHashMapjdk 7中的源代码并且几乎没有问题.我已经在StackOverFlow上完成了有关CHM的所有问题,但找不到答案.

  1. get()CHM中的操作是否保证put()由其他线程获得正确的值?我问这是因为get不是,synchronized除非它看到null值.null值如何确保其他线程正在更新相同的记录然后get与lock一起使用?

  2. 这与HashEntry存储键和值的静态类有关.

    一个.为什么这堂课最后?它只是为了确保没有人对它进行子类化吗?如果有人将其子类化,会发生什么 - 这有什么问题?

    湾 如何使下一个字段最终有助于获得线程安全?

    C.为什么Key也是最终的?(我不确定为什么Key也是最终的HashMap)

java collections multithreading concurrenthashmap java.util.concurrent

2
推荐指数
1
解决办法
1012
查看次数

Java:异步并发写入磁盘

我的主线程中有一个函数,它会将一些数据写入磁盘.我不希望我的主线程卡住(磁盘I/O的高延迟)并且创建一个新线程只是为了写入是一个矫枉过正.我决定使用ExecutorService.

ExecutorService executorService = Executors.newFixedThreadPool(3);

   Future future = executorService.submit(new Callable<Boolean>() {
    public Boolean call() throws Exception {
      logger.log(Level.INFO, "Writing data to disk");
      return writeToDisk();
    }
  });
Run Code Online (Sandbox Code Playgroud)

writeToDisk是写入磁盘的函数

这是一个很好的方式吗?有人可以提出更好的方法吗?

更新:数据大小将大于100 MB.磁盘带宽为40 MBps,因此写入操作可能需要几秒钟.我不希望调用函数卡住,因为它必须做其他工作,所以,我正在寻找一种方法来调度磁盘I/O异步执行调用线程.

我需要委派任务而忘记它!

java multithreading java.util.concurrent

2
推荐指数
1
解决办法
4738
查看次数

ReadWriteLock vs StampedLock

我一直在使用ReadWriteLock来实现/维护锁定习语.

自JDK8 StampedLock推出以来.由于RWLocks以其缓慢和糟糕的性能而闻名,因此StampedLock看起来像是另一种选择(它们不是可重入的,速度更快).

然而,除了性能之外,我认为StampedLock的维护和使用更加困难和复杂 - 例如线程现在可以自行解锁 - 因此应采取相应的措施.

StampedLock比RWLock有什么好处?

java multithreading java.util.concurrent java-8

2
推荐指数
1
解决办法
2646
查看次数

由CountedCompleter的文档和来源混淆

这是java.util.concurrent.CountedCompleter类的代码片段(JDK 1.8.0_25).

/**
 * If the pending count is nonzero, decrements the count;
 * otherwise invokes {@link #onCompletion(CountedCompleter)}
 * and then similarly tries to complete this task's completer,
 * if one exists, else marks this task as complete.
 */
public final void tryComplete() {
    CountedCompleter<?> a = this, s = a;
    for (int c;;) {
        if ((c = a.pending) == 0) {
            a.onCompletion(s);
            if ((a = (s = a).completer) == null) {
                s.quietlyComplete();
                return;
            }
        }
        else if …
Run Code Online (Sandbox Code Playgroud)

java concurrency java.util.concurrent forkjoinpool

2
推荐指数
1
解决办法
966
查看次数

以块的形式读取ConcurrentHashMap(或类似的)

我有一个程序,有一个ConcurrentHashMap不同的线程可以添加/删除地图中的项目.

我很想知道在25个项目中读取地图的最佳方法是什么.我想要做的是这样的:用户点击按钮并从地图中读取25个项目(与订单无关).之后,他可以单击"下一步"按钮并读取另外25个项目(与前25个项目不同),依此类推.

我不确定我是否可以这样做ConcurrentHashMap.我不想使用数据库,我想把它保存在内存中.我不认为转换Map成一个ArrayList会有帮助,因为大多数时候都会在地图中添加/删除项目.

我愿意接受任何解决方案,甚至是第三方库.

更新:我也没有被束缚ConcurrentHashMap.我只是在寻找最好的解决方案

更新2:他们的钥匙是String

谢谢

java concurrency hashmap java.util.concurrent

2
推荐指数
1
解决办法
390
查看次数

在Scala/Java中使用AtomicBoolean进行数据库锁定是否安全?

我有一个应用程序,我想确保一个方法最多同时调用一次,比如在数据库中更新用户余额时.

我正在考虑使用以下锁定机制:(显示下面的Scala代码,但应该与Java Lambdas类似):

object Foo{
    val dbLocked = new java.util.concurrent.atomic.AtomicBoolean(false)

    def usingAtoimcDB[T](f: => T):T = {
        if (dbLocked.get) throw new Exception("db is locked")
        dbLocked.set(true)
        try f
        finally dbLocked.set(false)    
    }
}
Run Code Online (Sandbox Code Playgroud)

usingAtoimcDB可以同时调用时使用是否安全?

编辑:下面更正的代码,如下面的答案所示:

def usingAtoimcDB[T](f: => T):T = {
  if(dbLocked.compareAndSet(false, true)) {
   //db is now locked
   try f
   finally dbLocked.set(false)
  } else {
   //db is already locked
   throw new Exception("db is locked")
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

使用spinloop.这也行吗?

def usingAtoimcDB[T](f: => T):T = {
  while (!dbLocked.compareAndSet(false, true)) {Thread.sleep(1)}
  try f …
Run Code Online (Sandbox Code Playgroud)

java multithreading scala java.util.concurrent

2
推荐指数
1
解决办法
989
查看次数

为什么lambda里面的地图没有运行?

我试图在java 8中学习并发和lambdas.但是我的代码没有在map中输入lambda块.

List<Book> bookList = new ArrayList<Book>();
    isbnList
    .stream()
    .map(isbn -> (CompletableFuture.supplyAsync( () -> {
        try {
            List<String> pageContents = getUrlContents(webLink + isbn);
            return new Book(
                parseBookTitle(pageContents),
                isbn,
                parseRank(pageContents)
            );
        } catch (IOException ex) {
            return null;
        }
    })).thenApply(a -> bookList.add(a))
    );
Run Code Online (Sandbox Code Playgroud)

在调试时,代码退出.map行,我得到空bookList.顺序代码给我正确的结果.

concurrency lambda java.util.concurrent java-8 concurrent.futures

2
推荐指数
1
解决办法
878
查看次数

你可以在你获得()的另一个线程上调用java.util.concurrent.Semaphore.release()吗?

我有一个java模块,它需要通过接口同时执行一组任务(为实现模块的框架提供低级控制和处理),但同时不是太多,java.util.concurrent.Semaphore似乎是完美的.

我不确定的一个问题是线程安全release()acquire()调用.一个线程可以获取信号量锁,后来另一个线程释放它吗?

java concurrency multithreading java.util.concurrent

2
推荐指数
1
解决办法
196
查看次数

并发访问ExecutorService

考虑以下服务类别:

//Singleton service
public class InquiryService{

    private final ExecutorService es = Executors. newSingleThreadExecutor();
    private final CustomerService cs = new CustomerServiceImpl();

    public String process(){

          //Asynchronous calls to get info from CustomerService
          Future<String> result = es.submit(()->{return cs.getCustomer()});

          //Query database
          //Perform logic et all

          String customerName = result.submit.get();

          //continue processing.
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的服务类具有一个ExecutorServiceas字段。如果说在process方法上有100个并发请求,那么剩下的(100-1)个请求是否需要等待线程可用性?

如何解决请求等待?我可以想到的一种选择是ExecutorServiceprocess方法内实例化,使用和关闭。但是,线程池不是要重用吗?

另一个选项将作为运行new Thread(new FutureTask<>(() -> {return cs.getCustomer()}))。哪一种是正确的方法?

更新:-

根据评论和答案,ExecutorService要重用和频繁Thread创建新内容的成本很高。因此,另一个选择是依次运行服务调用。

java multithreading java.util.concurrent

2
推荐指数
1
解决办法
83
查看次数