我需要每分钟运行一个线程来清理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时添加启动线程的条件?
答案 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中描述的逻辑,根据您不断变化的要求重新安排自己的任务。