简体   繁体   English

Java为每个数据库行创建唯一的线程

[英]Java create unique thread per database row

I have the requirement to poll the database every x seconds and pull out records that need to be processed. 我有要求每x秒轮询一次数据库,并提取需要处理的记录。 I will start a thread for each of these rows. 我将为每个这些行启动一个线程。 The next time I poll the threads may not have completed yet. 下次我轮询线程可能尚未完成。 I don't want to start another thread for the same ID as it is still processing. 我不想以相同的ID启动另一个线程,因为它仍在处理中。

A HashMap<String, Callable> seems appropriate for storing the threads and ensuring that only one thread per ID will exist . HashMap<String, Callable>似乎适合存储线程并确保每个ID仅存在一个线程。 What I can't figure out is how do I remove the thread after the thread is done? 我不知道是在线程完成后如何删除线程?

My understanding is that if I wait on the thread then it will be blocking the main thread and the polling will not continue. 我的理解是,如果我在线程上等待,那么它将阻塞主线程,并且轮询将不会继续。

I have tried the following code and it works, but the HashMap will continue to grow as more tasks come in. There is a possibility that the row could be reprocessed later in the day. 我已经尝试了以下代码,并且可以正常工作,但是随着更多任务的到来,HashMap将继续增长。有可能在当天晚些时候对该行进行重新处理。

HashMap<String, Callable<String>> callables = new HashMap<String, Callable<String>>();
for(int i =0; i < 10; i++)
{
    for(int j =0; j < 10; j++)
    {
        String key = Integer.toString(j);
        if(!callables.containsKey(key))
        {
            callables.put(key, new Callable<String>() {
                public String call() throws Exception {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Inside task");
                    return "Task Completed";
                }
            });
            try
            {
                callables.get(key).call();
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        else
            System.out.println("Task skipped: " + j);
    }
}

If your problem is to remove the couple (key, Callable) from your Map when the thread has finished its job. 如果您的问题是在线程完成其工作后从地图中移除夫妇(键,Callable)。 Call remove() at the end of its call() function. 在其call()函数的末尾调用remove()。

HashMap<String, Callable<String>> callables = new HashMap<String, 
Callable<String>>();
for(int i =0; i < 10; i++) {
    for(int j =0; j < 10; j++) {
        String key = Integer.toString(j);
        if(!callables.containsKey(key)) {
            callables.put(key, new Callable<String>() {
                final String mKey = key; //store the current key
                public String call() throws Exception {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Inside task");
                    callables.remove(mKey); //Remove the thread from the Map
                    return "Task Completed";
                }
            });
            try {
                callables.get(key).call();
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        }
        else
            System.out.println("Task skipped: " + j);
    }
}

You can wrap Callable s inside your own Callable . 您可以将Callable包装在您自己的Callable

HashMap<String, Callable<String>> callables = new HashMap<>();

public void oneOnly(String id, Callable<String> callable) {
    if (!callables.containsKey(id)) {
        // Wrap the callable in my own.
        callables.put(id, new Callable<String>() {
            public String call() throws Exception {
                String result = callable.call();
                // Remove when finished.
                callables.remove(id);
                return result;
            }
        });

    }
}

public void test(String[] args) throws Exception {
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            String key = Integer.toString(j);
            oneOnly(key, new Callable<String>() {
                public String call() throws Exception {
                    System.out.println("Inside task");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return "Task Completed";
                }
            });
            try {
                callables.get(key).call();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

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

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