【问题标题】:Java, Thread - Synchronized variableJava,线程 - 同步变量
【发布时间】:2013-09-09 13:57:16
【问题描述】:

如何在线程之间创建一个公共变量? 例如:许多线程向服务器发送请求以创建用户。

这些用户保存在一个ArrayList 中,但是这个ArrayList 必须为所有线程同步。我该怎么做?

谢谢大家!

【问题讨论】:

  • 创建变量。将其作为参数传递给Thread(您应该使用Runnable)构造函数。
  • 嗯,好的。在服务器类中(创建线程时,我传递所有公共变量,对吗?)。例如,ArrayList USERS 是 Server.java 中的静态变量。在 main 中,我以用户为线程的参数创建线程。
  • 是的,这是一种方法。

标签: java multithreading variables synchronization


【解决方案1】:

如果你要从多个线程访问列表,你可以使用 Collections 来包装它:

List<String> users = Collections.synchronizedList(new ArrayList<String>());

然后在构造函数中简单地将它传递给将要使用它的线程。

【讨论】:

    【解决方案2】:

    我会使用ExecutorService 并向其提交您想要执行的任务。这样你就不需要同步集合(可能根本不需要集合)

    但是,您可以按照您的建议进行操作,方法是创建一个用 Collections.synchronizedList() 包装的 ArrayList,并在启动之前将其作为对线程的引用。

    你可以做的是类似的事情

    // can be reused for other background tasks.
    ExecutorService executor = Executors.newFixedThreadPool(numThreads);
    
    List<Future<User>> userFutures = new ArrayList<>();
    for( users to create )
       userFutures.add(executor.submit(new Callable<User>() {
            public User call() {
                return created user;
            }
       });
    List<User> users = new ArrayList<>();
    for(Future<User> userFuture: userFutures)
       users.add(userFuture.get();
    

    【讨论】:

    • +1 因为它可能有助于完全避免同步。这是一件好事,一件好事,一件好事。
    • 我认为收藏仍然是必要的,因为最后他想要一份他们的清单。
    【解决方案3】:

    为了扩展@Peter 的答案,如果您使用ExecutorService,您可以提交Callable&lt;User&gt;,它可以返回由在另一个线程中运行的任务创建的User

    类似:

    // create a thread pool with 10 background threads
    ExecutorService threadPool = Executors.newFixedThreadPool(10);
    List<Future<User>> futures = new ArrayList<Future<User>>();
    for (String userName : userNamesToCreateCollection) {
        futures.add(threadPool.submit(new MyCallable(userName)));
    }
    // once you submit all of the jobs, we shutdown the pool, current jobs still run
    threadPool.shutdown();
    
    // now we wait for the produced users
    List<User> users = new ArrayList<User>();
    for (Future<User> future : futures) {
        // this waits for the job to complete and gets the User created
        // it also throws some exceptions that need to be caught/logged
        users.add(future.get());
    }
    ...
    
    private static class MyCallable implements Callable<User> {
        private String userName;
        public MyCallable(String userName) {
            this.userName = userName;
        }
        public User call() {
            // create the user...
            return user;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-27
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多