Java 在同一时间运行的线程实例

Java 在同一时间运行的线程实例,java,multithreading,Java,Multithreading,我有一个线程需求,我需要启动一个线程,该线程将连续运行,执行一些DB操作。第二个线程将出现,需要每30秒运行一次。第二个线程的任务是终止第一个线程并启动第一个线程的新实例 我尝试了几种方法来实现这一点,但我不能做到同样的 public class ThreadMain { public static void main(String[] args) throws InterruptedException, BrokenBarrierException{ final CyclicBar

我有一个线程需求,我需要启动一个线程,该线程将连续运行,执行一些DB操作。第二个线程将出现,需要每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();

这似乎很有效:

// 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);
    }
}

如果您的数据库任务是可中断的(即,它会对线程中断作出反应,因此可以通过线程中断取消),那么最好的策略是对数据库任务本身和定期运行的重启任务使用
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实现可运行{
公开募捐{
...
}
}
静态类RestartTask实现可运行{
私人最终执行人服务执行人;
私人部门的未来不稳定;
公共重新启动任务(ExecutorService executor){
this.executor=执行人;
}
公开募捐{
如果(未来!=null){
future.cancel(true);
}
future=executor.submit(newdatabasetask());
}
}
ScheduledExecutorService executor=执行者。newScheduledThreadPool(1);
executor.scheduleAtFixedRate(新的重新启动任务(executor)),0,30,时间单位为秒;

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

您可以向我们展示您的尝试吗?您尝试的几种方法中的任何一种?您好,我已经添加了上面的代码。但是这里它只是连续运行第二个线程。我得到的O/P是“连续运行线程:-线程2”。我不知道为什么第一个线程输出没有显示。理想情况下,它不会打印任何内容,因为参与方的数量设置为3。将它设置为2,它应该可以工作。虽然我不确定这是否符合你的目的。你的设计是。。。不寻常。当您发现自己编写的一个线程杀死了另一个线程,然后启动了一个新实例时,您应该问问自己,是否有其他方法来解决这个“解决方案”试图解决的更大问题。