Java为每个数据库行创建唯一线程
我需要每x秒轮询一次数据库,并取出需要处理的记录。我将为每一行启动一个线程。下次轮询时,线程可能尚未完成。我不想为同一ID启动另一个线程,因为它仍在处理Java为每个数据库行创建唯一线程,java,multithreading,Java,Multithreading,我需要每x秒轮询一次数据库,并取出需要处理的记录。我将为每一行启动一个线程。下次轮询时,线程可能尚未完成。我不想为同一ID启动另一个线程,因为它仍在处理 HashMap似乎适合于存储线程,并确保每个ID只存在一个线程。我不明白的是,在线程完成后如何删除线程 我的理解是,如果我在线程上等待,那么它将阻塞主线程,轮询将不会继续 我已经尝试了下面的代码,它是有效的,但是随着更多任务的到来,HashMap将继续增长。有可能在当天晚些时候重新处理该行 HashMap<String, Callable
HashMap
似乎适合于存储线程,并确保每个ID只存在一个线程。我不明白的是,在线程完成后如何删除线程
我的理解是,如果我在线程上等待,那么它将阻塞主线程,轮询将不会继续
我已经尝试了下面的代码,它是有效的,但是随着更多任务的到来,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);
}
}
HashMap callables=newhashmap();
对于(int i=0;i<10;i++)
{
对于(int j=0;j<10;j++)
{
字符串key=Integer.toString(j);
如果(!callables.containsKey(键))
{
put(key,newcallable()){
公共字符串调用()引发异常{
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“内部任务”);
返回“任务完成”;
}
});
尝试
{
callables.get(key.call();
}
捕获(例外情况除外){
例如printStackTrace();
}
}
其他的
System.out.println(“跳过任务:+j”);
}
}
如果您的问题是在线程完成其工作后从映射中删除该对(键,可调用)。在其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);
}
}
HashMap callables=newhashmap();
对于(int i=0;i<10;i++){
对于(int j=0;j<10;j++){
字符串key=Integer.toString(j);
如果(!callables.containsKey(键)){
put(key,newcallable()){
最后一个字符串mKey=key;//存储当前密钥
公共字符串调用()引发异常{
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“内部任务”);
callables.remove(mKey);//从映射中删除线程
返回“任务完成”;
}
});
试一试{
callables.get(key.call();
}
捕获(例外情况除外){
例如printStackTrace();
}
}
其他的
System.out.println(“跳过任务:+j”);
}
}
您可以将Callable
s包装在自己的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();
}
}
}
}
HashMap callables=newhashmap();
public void oneOnly(字符串id,可调用){
如果(!callables.containsKey(id)){
//把电话包在我自己的里面。
put(id,newcallable()){
公共字符串调用()引发异常{
String result=callable.call();
//完成后移除。
callables.remove(id);
返回结果;
}
});
}
}
公共无效测试(字符串[]args)引发异常{
对于(int i=0;i<10;i++){
对于(int j=0;j<10;j++){
字符串key=Integer.toString(j);
oneOnly(键,新可调用(){
公共字符串调用()引发异常{
System.out.println(“内部任务”);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
返回“任务完成”;
}
});
试一试{
callables.get(key.call();
}捕获(例外情况除外){
例如printStackTrace();
}
}
}
}
为什么要将整数转换为字符串?为什么不直接使用整数作为键呢?双循环的作用是什么?我正在设计一个例子来帮助说明这个问题。我的实际密钥将是一个字符串。双循环是为了证明下一次通过“键”将不再被处理,因为您需要一个线程池。您还需要忘记线程,使用Executor/ThreadPool,等等。这听起来像是一场即将发生的灾难。我不认为你被允许访问lambda之外的物品。“我不明白你是怎么把钥匙放进mKey的?”理查德宾宁顿编辑后在mKey里加了钥匙谢谢你,先生!我非常感激!