如何使ScheduleTask在特定时间执行一次任务?

时间:2019-01-31 09:35:02

标签: java multithreading scheduledexecutorservice

最近与ScheduleTask合作,我有这样一个问题。我希望我的ScheduleTask在地图大小大于MAX_SIZE字段时每5秒从地图中删除一次元素。我正在尝试这样做:

public class RemoverThread extends TimerTask {

    private AbstractCustomCache customCache;
    private static final int MAX_SIZE = 2;

    public RemoverThread(AbstractCustomCache customCache) {
        this.customCache = customCache;
    }

    @Override
    public void run() {
        if (customCache.getCacheEntry().size() > MAX_SIZE) {
            List<String> gg = new ArrayList<>(customCache.getCacheEntry().keySet());
            for (String s : gg) {
                System.out.println("Element was remove: " + customCache.getCacheEntry().remove(s));
                System.out.println("Time: " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime()));
                if (customCache.getCacheEntry().size() <= MAX_SIZE) {
                    break;
                }
            }
        }
    }
}

我的主:

public class Main {
    public static void main(String[] args) {
        AbstractCustomCacheStatistics gh = new MapCacheStatistics();
        AbstractCustomCache gg = new MapCache(gh);


        for (int i = 0; i < 5; i++){
            gg.put("ab" + i);
        }
        RemoverThread removerThread = new RemoverThread(gg);
        Executors.newScheduledThreadPool(2).scheduleAtFixedRate(removerThread, 5, 5, TimeUnit.SECONDS);

        for (int i = 0; i < 3; i++){
            gg.put("abc" + i);
        }
    }
}

AbstractCustomCache:

public abstract class AbstractCustomCache implements CustomCache{

    private Map<String, CacheEntry> cacheEntry = new LinkedHashMap<>();

    public Map<String, CacheEntry> getCacheEntry() {
        return Collections.synchronizedMap(cacheEntry);
    }
}

我在输出中得到了这个

Element was remove: CacheEntry{field='ab0'}
Time: 2019/01/31 11:39:11
Element was remove: CacheEntry{field='ab1'}
Time: 2019/01/31 11:39:11
Element was remove: CacheEntry{field='ab2'}
Time: 2019/01/31 11:39:11
Element was remove: CacheEntry{field='ab3'}
Time: 2019/01/31 11:39:11
Element was remove: CacheEntry{field='ab4'}
Time: 2019/01/31 11:39:11
Element was remove: CacheEntry{field='abc0'}
Time: 2019/01/31 11:39:11

我在做什么错?如何改善?我想每5秒从地图中删除一次。例如,我添加了ab0, ab1, ab2, ab3, ab4。该流应删除ab0, ab1, ab2。由于地图中的元素大于MAX_SIZE。然后我添加abc0, abc1, abc2。在删除第一个元素后5秒钟,应删除ab3, ab4, abc0。但是,如您所见,所有项目都被同时删除。

1 个答案:

答案 0 :(得分:1)

  

我在做什么错了?

  1. 使用Executors.newScheduledThreadPool(2).scheduleAtFixedRate(removerThread, 5, 5, TimeUnit.SECONDS);,第一个执行时间将是delayed x 5秒,那时缓存包含:ab0 ab1 ab2 ab3 ab4 abc0 abc1 ab2,前5个将是删除。

  2. 您需要一个线程安全版本AbstractCustomCache customCache,因为它是由多个线程修改的。