在一个周期内从一个线程切换到另一个线程(java)

在一个周期内从一个线程切换到另一个线程(java),java,multithreading,Java,Multithreading,这是我的问题:当我编写一个小软件使焰火出现在java中时,我选择给焰火中的每个保险丝一个线程。现在,我有一个熔断器的链接列表,每个熔断器都有一个线程,这些线程都包含在等待某个时间,然后逐直径绘制熔断器,以获得这种外观: 保险丝保持通电一段时间,然后将其涂成黑色并停止接线 问题是,因为所有的线都是从一起开始的,它们不断重叠,并用彼此的颜色或位置绘制东西,导致我的保险丝看起来像这样: 我试图找到一种方法,给每根线几秒钟的时间来画一个直径,然后停止它,然后转到下一个直径,循环,这样所有直径都可以一

这是我的问题:当我编写一个小软件使焰火出现在java中时,我选择给焰火中的每个保险丝一个线程。现在,我有一个熔断器的链接列表,每个熔断器都有一个线程,这些线程都包含在等待某个时间,然后逐直径绘制熔断器,以获得这种外观:

保险丝保持通电一段时间,然后将其涂成黑色并停止接线

问题是,因为所有的线都是从一起开始的,它们不断重叠,并用彼此的颜色或位置绘制东西,导致我的保险丝看起来像这样:

我试图找到一种方法,给每根线几秒钟的时间来画一个直径,然后停止它,然后转到下一个直径,循环,这样所有直径都可以一个接一个地画出来(这种方式的爆炸效果比一次画整个保险丝要漂亮得多)。这样,一次只能有一个活动线程,但它们都会定期有机会做一些事情。我尝试了几种不同的方法,我把最好的放在这里,但即使这样也不能完全奏效!如果你们中的任何一个人有一个想法,如何在一个线程列表中遍历一定次数,给每个线程几秒钟,然后再遍历一遍,那就太好了

public void peindre(Graphics gr){       
            gr.setColor(Color.black);
            gr.fillRect(0, 0, w, h); 
            for (Fusee fus : fusees) {
                fus.g = gr ;
                if (fus.num > numMax){
                    numMax = fus.num ; 
                }
                if (fus.puissEtincelles > puissEtincellesMax){
                    puissEtincellesMax = fus.puissEtincelles ; 
                fus.anim.start(); 
            }
            for (int k = 1; k<=puissEtincellesMax ; k++ ){  //k is the number of diameters drawn
                int i =1 ;  
                if (i != numMax) {
                    for (Fusee fus : fusees) {
                        if (fus.num != i) {  
                            try {
                                fus.anim.wait();
                            }
                            catch(InterruptedException e) {
                                System.out.println(e);
                            }
                    i += 1 ;   
                }
                }
                }
                else if (i==numMax){
                    i = 1 ; 
            }   
        }
    }
public void peindre(图形组){
gr.setColor(颜色为黑色);
gr.fillRect(0,0,w,h);
for(Fusee-fus:fusees){
fus.g=gr;
如果(fus.num>numMax){
numMax=fus.num;
}
如果(fus.puissEtincelles>puissEtincellesMax){
puissetincelsmax=fus.puissEtincelles;
fus.anim.start();
}

对于(int k=1;k如果我正确理解了这一点,您希望您的程序按顺序/线性运行。列表中的每个保险丝都按顺序处理:

保险丝1>保险丝2>保险丝3>保险丝4>

你不需要线程来实现这种行为。线程是并发运行的。正如你所说的,它们可以并且会相互重叠(只要你的CPU愿意,它们就会执行)。通过运行线程并强制它们执行顺序操作,你基本上会“破坏”线程提供给你的一切

如果仍要使用线程,可以使用
synchronize
关键字将其同步,如下所示:

//Your run method
public void run()
{
    synchronized(this)
    {
        //Your code in the run method
    }
}
synchronize
块中的所有内容一次只能由一个线程处理。所有其他线程将等待,直到当前处理线程完成其工作

+++++++++++++++++++++++++++++++++++++++编辑+++++++++++++++++++++++++++++ 实际上,有一个接口,它允许您计划
可运行文件的执行。它包含在
java.util.concurrent
中,名为
ScheduledExecutorService

您可以为这类任务使用的方法是
scheduleAtFixedRate(…)
。它使您能够运行以初始延迟开始的周期性操作

//First, lets create the scheduler. Replace NUM_OF_FUSES with the actual number
//or in your case the size of the fuse-List
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(NUM_OF_FUSES);

//Now we add all of your fuses (aka. Runnables/Threads) into this pool
//(assuming your List of fuses is called 'fuselist' and each 'Fuse'
//is 'Runnable')
long delay = 0;
long repeat = 3;
for(Fuse fuse: fuselist)
{
    //What this does is:
    //It adds each of your threads to the pool. Each thread kicks of with a certain delay. The
    //first on kicks right off, since the delay is 0, the second kicks off after 1 second ...
    //After the thread has done its work it will repeat itself after 3 seconds.
    //.scheduleAtFixedRate(Runnable runnable,long delay,long repeat, TimeUnit unit)
    scheduler.scheduleAtFixedRate(fuse, delay, repeat, TimeUnit.SECONDS)
    delay++;
}

//To stop all of your threads you'd call...
//...to let your threads finish their work
scheduler.shutdown();

//...or this to stop them right now, without waiting for each Thread to finish thw work
scheduler.shutdownNow();

听起来你不想要线程;你真的想要顺序的、线性的处理。也许错误在于假设线程是正确的方式。如果你只想按固定的顺序做事情,你不需要线程。你可以使用标准的线程类从一个循环启动n个线程并停止/启动它们。谷歌可以告诉你怎么做。基于计时器的解决方案不是更好吗?每次爆炸都在某个时间和地点开始,每次时钟滴答作响,距离原点稍远。@JoopEggen是的,我想基于时间的解决方案是有意义的,但我不知道如何编程这种事情!这是我第一次用线程和我只是被告知它们是保护我的保险丝的最佳方式,这就是我开始使用它们的原因……但你如何编程一个独立运行的时钟,以便每个保险丝都能读取其值?感谢你的帮助@NateStone,但是我担心如果我同步保险丝,由于只有一个保险丝,它们将无法同时爆炸线程将能够访问图形环境…实际上,我只是希望这些不同的保险丝能够同时爆炸,但在不同的线程中,每个线程都保持自己的颜色。这就是为什么我想查看线程列表并激活一个线程几秒钟,然后激活下一个线程,然后像那样通过w孔列了一定的次数…我希望这更清楚我很抱歉这很难解释!
//First, lets create the scheduler. Replace NUM_OF_FUSES with the actual number
//or in your case the size of the fuse-List
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(NUM_OF_FUSES);

//Now we add all of your fuses (aka. Runnables/Threads) into this pool
//(assuming your List of fuses is called 'fuselist' and each 'Fuse'
//is 'Runnable')
long delay = 0;
long repeat = 3;
for(Fuse fuse: fuselist)
{
    //What this does is:
    //It adds each of your threads to the pool. Each thread kicks of with a certain delay. The
    //first on kicks right off, since the delay is 0, the second kicks off after 1 second ...
    //After the thread has done its work it will repeat itself after 3 seconds.
    //.scheduleAtFixedRate(Runnable runnable,long delay,long repeat, TimeUnit unit)
    scheduler.scheduleAtFixedRate(fuse, delay, repeat, TimeUnit.SECONDS)
    delay++;
}

//To stop all of your threads you'd call...
//...to let your threads finish their work
scheduler.shutdown();

//...or this to stop them right now, without waiting for each Thread to finish thw work
scheduler.shutdownNow();