同时在Java中运行两个类

时间:2013-07-19 13:34:09

标签: java audio synchronization synchronized

我一直在努力解决这个问题两个小时,但仍然无法找到解决方案。

实际上我是Java新手,对Java synchronized一点也不熟悉。我甚至不知道是否需要使用synchronized来实现我的需要。

这是我的包的结构。

----------------------------
|----recorder.java
|          -------captureScreen.java
|          -------captureSound.java
                     |----start();
                     |----stop();

我正在为我的网络应用构建一个屏幕录像机。我已经制作了屏幕捕获器和一个可以录制音频的单独类。但我无法让它们同时工作。

我有

captureSound sound = new captureSound();

当我开始录音时,它一直等到我停止录音机。 这里是我的问题所在。我想做的是做完sound.start()我的程序应该执行recorder.java的其他语句,即recorder.java不应该等待执行captureSound()。但它停止了。如何使它们同时运行?这样我以后就可以从sound.stop()本身recorder.java开始。

2 个答案:

答案 0 :(得分:2)

我怀疑你的意思是你希望它们同时运行。这意味着使用两个+线程。我建议您为捕获采用时间戳,以便将它们与录音结合起来。

答案 1 :(得分:2)

同步的内容

synchronized关键字意味着一些事情

  1. synchronized包围的部分不能在同一对象同步的区域中运行多个线程,换句话说,您是保证同步访问,即isTrue在当前内容的同步部分中是false,除非当前在同步部分中的线程起作用,否则它将保持该值。
  2. 这也意味着操作不会为优化目的重新排序
  3. 当用作方法描述符时,具有以下类型样式的方法
    public synchronized void doWork(Object parameter)
    {
        /*do stuff*/
    }

    转换为以下内容:
    public synchronized void doWork(Object parameter)
    { 
        synchronized(this)
        { 
            /*do stuff*/ 
        } 
    }

同步不会神奇地启动线程

你需要自己启动线程,我不能告诉你有多少次我发现人们认为只是因为你创建一个方法或者一个同步块在没有他们做任何工作的情况下神奇地旋转一个线程,这是一种方式控制对代码关键部分的访问

创建新线程

有几种方法可以做到这一点,但最好的方法(IMO)是使用一个实现Runnable的类并让你的线程使用它


Recorder recordIn= new Recorder();
Scanner scanIn= new Scanner();
Thread threadRecord = new Thread(new Runnable() {

    private final Recorder target = recordIn;
    @Override
    public void run() {
    //do stuff in here
    }

}); Thread threadScan = new Thread(new Runnable() { private final Recorder targetsRecorder = recordIn; private final Scanner target = scanIn; @Override public void run() { //do stuff here
}

});

threadRecords.start(); threadScan.start();

确保您的代码正常运行

现在您需要确保您的同步代码有效。根据您的尝试,您需要关注不同的事情。一个常用的例子是在一个线程上有线程等待,你可以通过等待对象句柄来完成。例如,我想在每次注意到移动时扫描记录器。 另外,请记住我在没有IDE的情况下即时执行此操作,并且我假设只有这两个线程正在对象执行操作

    private final Recorder target = recordIn;
    @Override
    public void run() {
    //do stuff in here
    }

使用事件列表器

执行此操作

正如你所说,你正在使用事件监听器这样做,这个概念是相同的,只是在事件列表器中启动一个新线程


Thread threadRecord = new Thread(new Runnable() {

    private final Recorder target = recordIn;
    private final Scanner scanr= scanIn;     
    @Override
    public void run() {
        //if movement is noticed compared to the last frame save 
        recordIn.startRecording();
        while(true){
            synchronized(target ){
                while(target.hasMore()){

                   synchronized(scanr)
                   {
                       while(!target.currentImage().equals(scanr.getLatestImage())
                       {
                           target.recordMore();    
                           scanr.wait();
                       }
                   }
                 }
            }
        }
     }
}

}); Thread threadScan = new Thread(new Runnable() { private final Recorder targetsRecorder = recordIn; private final Scanner target = scanIn; @Override public void run() { //do stuff here synchronized(target){ target.wait(); while(true) { while(!targetsRecorder.doneRecording() && targetsRecorder.currentImage().equals(scanIn.getLastImage())) target.wait();

                if(targetsRecorder.doneRecording())
                    return;

                scanIn.scanCurrentImage(targetsRecorder);
             }
        }       
}

}
});

threadScan.start(); threadRecord.start();