Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查s3对象是否已被另一个java线程拾取_Java_Multithreading_Amazon S3 - Fatal编程技术网

检查s3对象是否已被另一个java线程拾取

检查s3对象是否已被另一个java线程拾取,java,multithreading,amazon-s3,Java,Multithreading,Amazon S3,我有一个预定的任务,它不断检查s3存储桶,一次拾取所有条目并进行处理。 我的任务以10秒的间隔运行。我在阅读对象后立即将其删除。但有时多个任务会拾取同一对象。我怎样才能避免这种情况 public void execute(){ AmazonS3 s3 = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey)); List<S3ObjectSummary> summaries = readEmailsAndM

我有一个预定的任务,它不断检查s3存储桶,一次拾取所有条目并进行处理。 我的任务以10秒的间隔运行。我在阅读对象后立即将其删除。但有时多个任务会拾取同一对象。我怎样才能避免这种情况

public void execute(){

AmazonS3 s3 = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
List<S3ObjectSummary> summaries = readEmailsAndMoveToRead(s3, incomingBucket, customerId);
        if (summaries != null)
                for (S3ObjectSummary s3ObjectSummary : summaries) {
                    String key = s3ObjectSummary.getKey();// getting the key of
                                                            // the item
                    try {
                        S3Object object = s3.getObject(new GetObjectRequest(incomingBucket, key));
                        InputStream mailFileInputStream = object.getObjectContent();
                        String bucketKey = object.getKey();
                        s3.deleteObject(incomingBucket, bucketKey);
                        MimeMessage message = getMimeMessageForRawEmailString(mailFileInputStream);
                        object.close();
                        boolean isProcessed = processMessage(message);
                        if (isProcessed) {
                            logger.logDebug(CLASSNAME, "Processed successfully");

                        } else {
                            logger.logError(CLASSNAME, "Processing Error");

                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.logDebug(CLASSNAME, "This s3 object is already processed and deleted");
                    }

                }
}
public void execute(){
AmazonS3 s3=新的AmazonS3客户端(新的BasicAWSCredentials(accessKey、secretKey));
列表摘要=ReadEmail和MoveToRead(s3,incomingBucket,customerId);
如果(摘要!=null)
for(S3ObjectSummary S3ObjectSummary:摘要){
String key=s3ObjectSummary.getKey();//获取
//项目
试一试{
S3Object object=s3.getObject(新的GetObjectRequest(incomingBucket,key));
InputStream mailFileInputStream=object.getObjectContent();
字符串bucketKey=object.getKey();
s3.删除对象(incomingBucket、bucketKey);
MimeMessage message=getMimeMessageForRawEmailString(mailFileInputStream);
object.close();
布尔值isProcessed=processMessage(消息);
如果(已处理){
logger.logDebug(类名,“已成功处理”);
}否则{
logger.logError(类名,“处理错误”);
}
}捕获(例外e){
e、 printStackTrace();
logDebug(类名,“此s3对象已被处理并删除”);
}
}
}

您是否尝试使用闩锁或互斥锁,以便在已使用对象时阻止其他任务?在多线程环境中使用方法之前,还应该检查方法是否是线程安全的


e:如果您不熟悉并发,您应该阅读一些关于并发的内容,它一点也不直截了当:

S3本身没有任何帮助,因为S3的一致性模型不能保证删除的对象永远不会出现在后续的对象列表中。。。但是,如果您正在阅读新的电子邮件,并且这些电子邮件是由SES编写的,为什么不在SQS队列中收集通知事件(例如通过SES>SNS>SQS),而不是轮询bucket?我认为问题中的“对象”指的是存储在S3中的对象,而不是编程对象。OP从S3获取这些对象的列表,遍历列表,处理和删除对象,可能不知道列出对象是一个最终一致的操作,可能包含最近删除的对象,在某些情况下甚至可能仍然可以获取,因为删除操作本身是一个最终一致的操作。哦,好的。所以这是事务的问题。不确切地说,因为S3本身不是事务性的,但这是一个不错的类比。请看,这里使用的服务显然有点超出其设计规范。删除对象后列出对象可能(短暂)返回包含已删除对象的列表。或我可能对这个问题读得太多了,你的答案可能比我想象的更接近。这就是为什么没有否决票。干杯。谢谢你的信息和链接。