每分钟运行一次线程或其他条件

时间:2014-10-13 15:58:37

标签: java multithreading

我需要每分钟运行一个线程来清理DB中的表,我在while(true)循环中使用sleep(1000)。但是,如果List的大小大于X,我需要清理同一个表。我真的无法找到如何制作它。 (除了睡觉(1000)方式)你们可以帮助我吗?

这是我的代码:

public class TrxJanitor implements Runnable {

    private Thread t;
    private List<UUID> idList;

    public List<UUID> getIdList() {
        return idList;
    }

    /* getters and setters*/

       public void start()
       {
          if (t == null)
          {
             t = new Thread(this);
             t.start();
          }
       }

    public void addToJanitorList(UUID id){
        idList.add(id);
    }

    @Override
    public void run() {                 
            System.out.println("Running...");
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("account-pu");                    
            while (true) {
            // create EM tx1 and tx2
                EntityManager em = emf.createEntityManager();

                em.getTransaction().begin();

                System.out.println("Trying to delete from DB...");
                if(!idList.isEmpty()) {
                    for (UUID id : idList) {                
                        em.createNativeQuery("DELETE FROM TrxIdList WHERE Id LIKE '"+id+"'").executeUpdate();
                        System.out.println("DELETED THIS ID: "+id );
                    }
                    idList.removeAll(idList);
                }
                em.getTransaction().commit();
                System.out.println("DATA IN DB:\n");

              // print all lines of table
                @SuppressWarnings("unchecked")
                List<TrxIdList> ids = em.createNativeQuery("SELECT * FROM TrxIdList", TrxIdList.class).getResultList();
                if (!ids.isEmpty()) {
                    System.out.println("DB ROWS:\n");
                    int i = 0;
                    for (TrxIdList id : ids)
                    {
                         System.out.println("TRX_ID: "+id.getId() + " DATA: "+ id.getCreationTs()+"\n");
                         i++;
                    }
                    System.out.println("There are still a total of "+i+" lines in this table!");
                }

                em.close();

                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

    }


}

在这里我开始我的主题:

public class PopulateTrxIdTable {

    public static void main(String[] args) {

        TrxJanitor t = new TrxJanitor();
        t.start();
        System.out.println("All records inserted!");        
        System.out.println("Going to sleep!");
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {          
                e.printStackTrace();
            }
        System.out.println("Waking up!");       
        System.out.println("DONE!");
        System.out.println("Inserting into DB...");

        insertIntoDb(t);
    }

    private static void insertIntoDb(TrxJanitor t) {

        boolean pair = true;
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("account-pu");

        // create EM 
        EntityManager em1 = emf.createEntityManager();

        em1.getTransaction().begin();

        for (int i=0; i< 10000; i++) {
        //populates DB with the values returned by fillIds()
            if(i%2==0){
                pair = true;
            } else {
                pair = false;
            }
            em1.persist(fillIds(t, pair));

        }
        em1.getTransaction().commit();
        em1.close();
        emf.close();
    }

    private static TrxIdList fillIds(TrxJanitor j, boolean pair) {

        TrxIdList p = new TrxIdList();
        Random rand = new Random();

        //populates de DB with random ids and random dates (dates within range)        
        int randomNum = rand.nextInt((10 - 0) + 1) + 0;
        UUID id = UUID.randomUUID();    
        p.setId(id.toString());
        p.setCreationTs(notToday(randomNum)); //notToday returns a random timestamp
        if (pair) {
            j.addToJanitorList(id);
        }
        return p;

    }

}

如何更改此项,以便在idList大小大于X时添加启动线程的条件?

3 个答案:

答案 0 :(得分:0)

我会查看ScheduledExecutorService并让它定期执行Runnable。例如,以下代码应该每分钟从TrxJanitor运行“run”方法:

 import static java.util.concurrent.TimeUnit.*;
 public class PopulateTrxIdTable {
   private final ScheduledExecutorService scheduler =
     Executors.newScheduledThreadPool(1);

   public static void main(String[] args) {
     scheduler.schedule(new TrxJanitor(), 1, SECONDS);
   }
 }

答案 1 :(得分:0)

您应该使用显示器执行此任务。

它允许你在监视器上等待一个特定的时间(注意它有一个等待超时超载),诀窍是当你在监视器上等待时 - 等待可以在两种情况下中断 - 或者时间流逝或有人在监视器对象上调用通知。

基本用法示例:

final Object mon = new Object();

// This thread waits on a monitor for 1000msec, unless the other guy wakes him up first...
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            System.out.println("Sleep 1000");
            synchronized (mon) {
                mon.wait(1000);
            }
        } catch (InterruptedException e) { }
    }
}).start();

// this thread will flip a coin and wake up the waiting thread if it hits tails
new Thread(new Runnable() {
    @Override
    public void run() {
        if (new Random().nextBoolean()) {
            System.out.println("Wake early!");
            synchronized (mon) {
                mon.notify();
            }
        }
    }
}).start();

请查看this answer以获得更详细的说明。

答案 2 :(得分:0)

您可以创建一个像Minh Nguyen建议的ScheduledExecutorService,但使用this answer中描述的逻辑,根据您不断变化的要求重新安排自己的任务。

相关问题