简体   繁体   English

Java,线程-同步变量

[英]Java, Thread - Synchronized variable

How do I create a common variable between threads? 如何在线程之间创建公共变量? For example: Many threads sending a request to server to create users. 例如:许多线程向服务器发送请求以创建用户。

These users are saved in an ArrayList , but this ArrayList must be synchronized for all threads. 这些用户保存在ArrayList ,但是必须为所有线程同步此ArrayList How can I do it ? 我该怎么做 ?

Thanks all! 谢谢大家!

If you are going to access the list from multiple threads, you can use Collections to wrap it: 如果要从多个线程访问列表,则可以使用“集合”将其包装:

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

and then simply pass it in a constructor to the threads that will use it. 然后只需将其在构造函​​数中传递给将使用它的线程即可。

I would use an ExecutorService and submit tasks to it you want to perform. 我将使用ExecutorService并向您要执行的任务提交任务。 This way you don't need a synchronized collection (possibly don't need the collection at all) 这样,您就不需要同步的集合(可能根本不需要集合)

However, you can do what you suggest by creating an ArrayList wrapped with a Collections.synchronizedList() and pass this as a reference to the thread before you start it. 但是,您可以通过创建一个用Collections.synchronizedList()包装的ArrayList来做建议,然后在启动它之前将其作为对线程的引用。

What you could do is something like 你能做的就是

// 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();

To expand on @Peter's answer, if you use an ExecutorService you can submit a Callable<User> which can return the User that was created by the task run in another thread. 为了扩展@Peter的答案,如果您使用ExecutorService ,则可以提交Callable<User> ,它可以返回由在另一个线程中运行的任务创建的User

Something like: 就像是:

// 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM