同时在Java中运行两个类[关闭]

Posted

技术标签:

【中文标题】同时在Java中运行两个类[关闭]【英文标题】:Running two classes in Java concurrently [closed] 【发布时间】:2013-07-19 13:34:09 【问题描述】:

我已经为这个问题苦苦挣扎了两个小时,但仍然找不到解决方案。

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

这是我的包的结构。

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

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

我有

captureSound sound = new captureSound();

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

【问题讨论】:

花点时间educate yourself. 听起来你应该使用多线程或其他一些并发执行结构。 提示:使用线程:docs.oracle.com/javase/7/docs/api/java/lang/Thread.html @MattBall 我确实看到了。我的理解是,在将start()stop() 声明为同步时,recorder.java 不应该等待start() 完成。我是从某个给出颜色示例的地方得到的。 【参考方案1】:

Synchronized 做什么

synchronized 关键字意味着几件事

    synchronized 包围的部分不能有多个线程在同一个对象同步的区域中运行,换句话说,如果isTruefalse 在一个同步部分,在当前内容中,除非当前在同步部分中的线程对其进行操作,否则它将保持该值。 这也意味着操作不会为了优化目的而重新排序 当用作方法描述符时,即具有具有以下样式的方法
    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 的情况下即时执行此操作的,并且我假设只有这两个线程在操作对象上


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();

使用事件监听器进行此操作

正如您所说,您正在使用事件侦听器执行此操作,概念是相同的,只是在事件侦听器中启动一个新线程


//inside of your listner
public void someRecordEventHappened(RecordEvent event)
    new Thread(new Runnable
    
         private final RecordEvent eventDate = event;
         @Override
         public void run()
         
             //do stuff asynchronously
         
    ).start();

【讨论】:

没有别的办法了吗?我正在打开录制窗口并让播放/暂停事件侦听器 recorder.java 文件中的所有内容。这意味着如果我使用这种方式(屏幕录像机和录音机有两个不同的线程),我将不得不改变太多。即必须创建一个具有所有播放/暂停功能的新类。:(【参考方案2】:

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

【讨论】:

@OptimusPrime 让一个线程捕获音频,而另一个线程捕获屏幕。这样它们就可以同时完成,并且音频不需要停止。 @OptimusPrime 你想说asynchronously ;-) @OptimusPrime 同步意味着同步,但在 Java 中它很容易与 synchronized 混淆,这意味着可以由多个线程使用,但通常一次使用一个。 @PeterLawrey 没有其他方法可以解决这个问题吗?我正在打开录制窗口并让播放/暂停事件侦听器 recorder.java 文件中的所有内容。这意味着如果我使用这种方式(屏幕录像机和录音机有两个不同的线程),我将不得不改变太多。即必须创建一个具有所有播放/暂停功能的新类。:( @OptimusPrime 在 Java 中添加类和线程非常简单,我无法想象任何更简单的方法可以可靠地工作。

以上是关于同时在Java中运行两个类[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

两个线程不能同时作用于同一个对象吗[关闭]

有没有办法在java中同时运行两个GUI

如果我在同一个类上同步了两个方法,它们可以同时运行吗?

如何确保JAVA程序在一台机器上不能同时运行两个实例

Java之多线程详解

C++中如何同时运行俩个dos命令?