当前位置: 首页 > 知识库问答 >
问题:

我们如何以循环方式使用多线程?

冷正青
2023-03-14

我想以多线程方式阅读10个邮件帐户的未读邮件。

但是如果线程池大小为5,那么将使用线程池中的5个线程。每个线程将读取一个邮件帐户。因此,一旦Thread_1读取了第一个邮箱,它应该会读取mailbox_6。那么线程2将读取mailbox_7。

当所有邮件帐户都被读取一次后,循环将从第一个邮件帐户开始。

我们如何在java中做到这一点?

共有3个答案

金高飞
2023-03-14

简单地创建任务的并发(或同步,在这种情况下并不重要)集合(可能是队列)怎么样?每个任务都将从电子邮件帐户中加载所需的数据。然后让每个线程从集合中获取一个任务,直到它为空。

每个线程都将有一个对该集合的引用,并将对其进行循环。当集合不为空时,从它中获取一个任务并对其进行处理。

江承嗣
2023-03-14

跟踪已读取的电子邮件帐户。例如定义这样的东西,

//total number of email accounts that need to be read.
private int noOfEmails=10;

//the thread pool that is used to read the emails
private ExecutorService threadPool = Executors.newFixedThreadPool(5);

//the tracker array that keeps track of the emails that 
//are already read. This array is cleared only after all 10
//emails are read. 
private ArrayList<String> emailTracker=new ArrayList<String>(noOfEmails);

//any changes to emailTracker should be synchronized as 
//this is a common data shared between all 5 threads.
private Object syncObject=new Object();

在Runnable实现中,检查emailTracker是否包含您的电子邮件帐户标识符,如果这样意味着它已被读取,则返回并等待emailTracker被清除。当所有10个电子邮件帐户都被读取时,它将被清除。

        if(emailTracker.contains(email.identifier))
        {
            return;
        }

        //read email.
        email.read();
        //simple synchronization.
        synchronized (syncObject)
        {
            //read email
            emailTracker.add(email.identifier);
            //if all emails are read, clear the tracker
            //This will allow reading of all the emails 
            //once again.
            if(emailTracker.size()==noOfEmails)
            {
                emailTracker.clear();
            }

        }
麹高远
2023-03-14

这应该很容易。创建一个包含 5 个线程的固定线程池,然后将 10 个作业提交到该池 -- 每个用户电子邮件帐户 1 个:

// create a thread pool with 5 workers
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// submit all 10 user email accounts to the pool to be processed in turn
for (UserEmail userEmail : userEmailsToProcess) {
    threadPool.submit(new EmailProcessor(userEmail));
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
...
// here's our runnable class which does the actual work
public class EmailProcessor implements Runnable {
    private UserEmail userEmail;
    public MyJobProcessor(UserEmail userEmail) {
        this.userEmail = userEmail;
    }
    public void run() {
        // read the user email
        ...
    }
}

UserEmail类可以保存要“读取”的电子邮件的文件名,或者可能是帐户名或其他内容。这将由您决定如何表示邮件帐户和要阅读的邮件。

[[ 来自评论:]]

我有10个邮箱,像..邮箱1...mailbox10,现在我从线程池中有5个线程,所以线程1将获取任何邮箱,所以让我们假设它将选择邮箱1,然后线程2将选择邮箱2,线程3将选择邮箱3,线程4将选择邮箱4,thread5将选择邮箱5,现在当线程1(已定义的特定时间段)将释放时,那么它应该选择邮箱6 - mailbox10, 任何尚未读取它的人都不应该从mailbox1 - mailbox5中选择任何邮箱,直到所有尚未读取的邮箱。

哦,我明白了。一种解决方案是让一个调度线程时不时地Hibernate和唤醒,以查看邮箱中是否有邮件。如果是这样,那么它会将一个作业提交给线程池,以便读取该邮箱。一旦邮箱被读取,线程返回并请求处理下一个邮箱。分派线程将继续向线程池添加邮箱,直到被告知停止。

如果电子邮件处理器中有大量上下文,那么您可以拥有线程池,但它们可以从阻塞队列中消耗

 类似资料:
  • 问题内容: 我是Java中的多线程和同步的新手。我正在尝试实现一项任务,其中给了我5个文件,每个文件将由一个特定线程读取。每个线程应从文件读取一行,然后将执行转发到下一个线程,依此类推。当所有5个线程都读取第一行时,然后再次从线程1运行行号开始。文件1中的2,依此类推。 并且在ReadFile(在run方法中实现Runnable的情况下,我正在尝试在bufferreader对象上进行同步。 需要帮

  • 我是java多线程和同步的新手。我试图实现一个任务,其中我给了5个文件,每个文件将由一个特定的线程读取。每个线程应该从文件中读取一行,然后将执行转发给下一个线程,依此类推。当所有5个线程读取第一行时,再次从线程1开始运行文件1的第2行,依此类推。 并且在ReadFile(实现Runnable的,在run方法中,我正在尝试在缓冲区读取器对象上同步。 需要帮助

  • 所以我正在编写代码,它将解析文件夹中的多个文本文件,收集它们的信息,并将这些信息保存在两个静态列表实例变量中。信息存放的顺序并不重要,因为我最终将对其进行排序。但由于某些原因,增加线程数不会影响速度。这是我的run方法和主方法中利用多线程的部分。 如果需要额外的信息,我基本上有一个静态实例变量作为我需要浏览的文件的数组,还有一个常量是线程数(为了测试目的手动更改)。如果我有4个线程和8个文件,每个

  • 假设我有一些这样的方法: 但我不想调用序列方法: 这很无聊。如果我添加一个新方法:,我需要添加手动:

  • 我已经写了这个生产者/消费者问题解决方案。它似乎在工作,而不是无限循环。我的印象是,pthread\u exit(NULL) 会让它停止,但老实说,我已经迷路了。有人能告诉我如何阻止循环的正确方向吗?

  • 我正在Android studio中制作一个应用程序,我有从1到的分类按钮。我就是这样创造它们的: 我现在要做的是循环遍历每个按钮,只保留第一个按钮启用。因此,我想将它们从禁用为,如下所示: 这显然不起作用,因为它没有引用特定的按钮,它只是一个字符串。但我希望这能让你看到我正在努力实现的目标。基本上,我只需要找到一种方法,如何使用索引来引用按钮。我怎么能这样做呢? 感谢任何帮助。谢谢你!