Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:方法的优化每10微秒运行一次_Java_Optimization_Timer_Raspberry Pi - Fatal编程技术网

Java:方法的优化每10微秒运行一次

Java:方法的优化每10微秒运行一次,java,optimization,timer,raspberry-pi,Java,Optimization,Timer,Raspberry Pi,编辑:我使用nanoTime()进行了一些println()ing,发现stepPins[pin].toggle()需要4226微秒。现在,我需要找到一种快速切换引脚的方法。 我正在制作一个控制音乐软驱阵列的程序。目前,我有一个方法,每10微秒运行一次,通过读取一个简短的01001011格式,其中1=tick floppie(有8个floppie),来勾选必要的floppie 由于某种原因,该代码运行速度太慢,导致音符频率相差太远 以下是方法及其类: public class Timer imp

编辑:我使用
nanoTime()
进行了一些
println()
ing,发现
stepPins[pin].toggle()
需要4226微秒。现在,我需要找到一种快速切换引脚的方法。

我正在制作一个控制音乐软驱阵列的程序。目前,我有一个方法,每10微秒运行一次,通过读取一个简短的01001011格式,其中1=tick floppie(有8个floppie),来勾选必要的floppie

由于某种原因,该代码运行速度太慢,导致音符频率相差太远

以下是方法及其类:

public class Timer implements Runnable
{
    @Override
    public void run()
    {
        int i = Main.currentSteps.get(Main.time);
        try
        {
            if (Main.time > Main.maxTime)
            {
                Main.executor.remove(Main.timer);
                FloppyController.resetAll();
            }
            if ((i & 1) == 1)
            {
                FloppyController.stepPin(0);
            }
            if ((i & 2) == 2)
            {
                FloppyController.stepPin(1);
            }
            if ((i & 4) == 4)
            {
                FloppyController.stepPin(2);
            }
            if ((i & 8) == 8)
            {
                FloppyController.stepPin(3);
            }
            if ((i & 16) == 16)
            {
                FloppyController.stepPin(4);
            }
            if ((i & 32) == 32)
            {
                FloppyController.stepPin(5);
            }
            if ((i & 64) == 64)
            {
                FloppyController.stepPin(6);
            }
            if ((i & 128) == 128)
            {
                FloppyController.stepPin(7);
            }
        }
        catch (Exception e) {}
        Main.time++;
    }
}
值得一提的是,我的
Main.java
类的相关部分:

public class Main
{
    public static ArrayList<Short> currentSteps;
    public static ArrayList<Note> all = new ArrayList<Note>();
    public static long maxTime = 0;
    public static ScheduledThreadPoolExecutor executor;
    public static Timer timer;

    public static int time;

    public static void main(String[] args) throws InterruptedException, InvalidMidiDataException, IOException, MidiUnavailableException
    {
        //initialize
        FloppyController.init();
        currentSteps = new ArrayList<Short>();
        FloppyController.resetAll();

        for (int o = 0; o < Math.ceil(maxTime / 10); o++)
        {
            currentSteps.add((short) 0);
        }

        //populate list
        for (Note n : all)
        {
            for (int a = Math.round(n.timeStart / 10); a <= Math.round(n.timeEnd / 10); a += n.wait)
            {
                currentSteps.set(a, (short) (currentSteps.get(a) + (((currentSteps.get(a) & (short) Math.pow(2, n.channel)) == Math.pow(2, n.channel)) ? 0 : Math.pow(2, n.channel))));
            }
        }

        //start play executions
        executor = new ScheduledThreadPoolExecutor(1);
        long resolution = 10; //# of microsecond iterations
        timer = new Timer();
        executor.scheduleAtFixedRate(timer, 0, resolution, TimeUnit.MICROSECONDS);
    }

我建议每个软盘驱动器启动一个线程,并使用两个字节数组作为缓冲区(让我们称它们为“A”和“B”)来安排声音。缓冲区应该足够大,可以播放几秒钟的音乐。伪代码如下所示:

  • 初始化:用音乐的前几秒填充缓冲区。启动从缓冲区读取的所有软盘线程
  • 主线程:用下一秒的音乐填充所有B缓冲区。等待软盘线程到达B缓冲区(经过的时间)。然后写A缓冲区,依此类推,直到乐谱耗尽
  • 软盘线程:读取当前缓冲区,要么使用忙等待(高清晰度,高CPU使用率),要么使用的“精确”版本(依赖于操作系统的定义,低CPU使用率)。通过System.nanoTime()与其他人保持同步。当A缓冲区耗尽时,切换到B缓冲区

假设
stepPin
正在阻塞,但只阻塞它的线程,这将使您的线程与这些延迟隔离。

是否
stepPin
阻塞(直到软盘发出声音)?将为主要问题添加方法,最好安排时间,不要运行
stepPin()
计时器不精确,它将尽力每x毫秒运行一次,但这取决于底层系统。@TT。有更好的选择吗?至少它比Thread.sleep好:请注意println()也有开销,而且Java中的控制台IO通常比较慢。我建议改为写入缓冲文件。我可以执行多线程吗?记住,我在吃覆盆子馅饼。只有一个核心。如果我运行多个Java进程,会有什么不同吗?你肯定可以启动几个线程——如果问题是阻塞IO,那么如果time to context switch