线程在同一时间运行

时间:2014-05-16 15:38:18

标签: java multithreading

我有一个需求线程,我需要启动一个线程,它将连续运行一些数据库操作。将存在第二个线程,需要每30秒运行一次。第二个线程的工作将是杀死第一个线程并启动第一个线程的新实例。

我尝试了几种方法来实现这一目标,但我无法做到这一点。

public class ThreadMain {

public static void main(String[] args) throws InterruptedException, BrokenBarrierException{

    final CyclicBarrier gate = new CyclicBarrier(3);

    Thread t1 = new Thread(){
        public void run(){
            try {
                gate.await();
                while(true)
                {
                     System.out.println("Thread1"); 
                     break;

                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }};
    Thread t2 = new Thread(){
        public void run(){
            try {
                gate.await();
                while(true)
                {
                     System.out.println("Continiously running thread:-Thread2");     

                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }};

    t1.start();
    t2.start();

2 个答案:

答案 0 :(得分:0)

这似乎很有效:

// Thread that runs forever.
volatile static Thread forEverThread = null;

static class ForEver implements Runnable {

    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(1000);
                System.out.println("For Ever!");
            }
        } catch (InterruptedException ex) {
            // Just quit if I was interrupted.
        }
    }

}

// Stop the thread if it is running.
private static void stopForeverThread() throws InterruptedException {
    // Skip if non-existent.
    if (forEverThread != null) {
        // Make sure no-one else is already doing it.
        synchronized (forEverThread) {
            // Still not null?
            if (forEverThread != null) {
                // Interrupt it.
                forEverThread.interrupt();
                // Wait for it to finish.
                forEverThread.join();
                // Clear it.
                forEverThread = null;
            }
        }
    }
}

private static void restartForeverThread() throws InterruptedException {
    System.out.println("Restarting...");
    // Stop it if it is running.
    stopForeverThread();
    // Start it again.
    forEverThread = new Thread(new ForEver());
    forEverThread.start();
    System.out.println("Restarted");
}

public static void start() throws InterruptedException {
    // Start it all up.
    restartForeverThread();
    // Timed event to restart it.
    Timer restartTimer = new Timer(true);
    restartTimer.scheduleAtFixedRate(
            new TimerTask() {
                @Override
                public void run() {
                    try {
                        // Restart every few seconds.
                        restartForeverThread();
                    } catch (InterruptedException ex) {
                        // We were interrupted during restart - Log it.
                    }
                }
                // Every few seconds.
            }, 0, 10 * 1000);

}

public static void main(String args[]) {
    try {
        // Start it all up.
        start();
        // Hang around for a while - to see what happens.
        Thread.sleep(60 * 1000);
    } catch (Throwable t) {
        t.printStackTrace(System.err);
    }
}

答案 1 :(得分:0)

如果您的数据库任务是可中断的(即它会对线程中断作出反应,因此可以取消),最好的策略是对数据库任务本身和运行的重启任务使用ScheduledExecutorService周期性。

请注意,任务线程是两回事:任务是应该运行的一项工作,线程是并行执行此操作的机制。

static class DatabaseTask implements Runnable {
    public void run() {
        ...
    }
}

static class RestartTask implements Runnable {
    private final ExecutorService executor;
    private volatile Future<Void> future;

    public RestartTask(ExecutorService executor) {
        this.executor = executor;
    }

    public void run() {
        if (future != null) {
            future.cancel(true);
        }
        future = executor.submit(new DatabaseTask());
    }
}

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new RestartTask(executor), 0, 30, TimeUnit.SECONDS);

请注意,如果您的DatabaseTask对线程中断不敏感并继续执行数据库操作,则执行数据库任务的线程数将不断增加 - 可能不是您想要的。因此,请确保所有阻塞数据库操作都是可中断的,或在合理的时间内终止。