Java 需要同步的帮助吗

Java 需要同步的帮助吗,java,android,Java,Android,我正在创建一个实时流媒体应用程序,但我在某一点上被卡住了。 这是我的代码: public synchronized byte[] getPicture(int Width, int Height) { FrameWidth = Width; FrameHeight = Height; try { while (!isPreviewOn) { wait(); }

我正在创建一个实时流媒体应用程序,但我在某一点上被卡住了。 这是我的代码:

public synchronized byte[] getPicture(int Width, int Height) {
    FrameWidth = Width;
    FrameHeight = Height;

    try {                           
        while (!isPreviewOn) {
            wait();
        }

        isDecoding = true;
        mAvailableFrame = false;

        c.setOneShotPreviewCallback(mPreviewCallback);                

        while (isDecoding) {
            wait();
        }

    }
    catch (Exception e) {   
        return null;
    }

    mAvailableFrame = false;

    return mCurrentFrame;
}

PreviewCallback mPreviewCallback = new PreviewCallback() {

    @Override
    public synchronized void onPreviewFrame(byte[] data, Camera camera) {
        int width = FrameWidth;
        int height = FrameHeight;

        // API 7
        int[] temp = new int[width*height];
        OutputStream out = new ByteArrayOutputStream();
        Bitmap bm = null;

        raw2jpg(temp, data, width, height);
        bm = Bitmap.createBitmap(temp, width, height, Bitmap.Config.RGB_565);
        bm.compress(CompressFormat.JPEG, 100, out);
        /*ref*/mCurrentFrame = ((ByteArrayOutputStream)out).toByteArray();
        mAvailableFrame = true;
        isDecoding = false;
        notify();                   
    }
};
调用Synchronized getPicture()时,当它正在执行时,没有其他线程可以在该实例上调用Synchronized方法。getPicture()在等待isDecoding时,持有实例上的锁。我怀疑setOneShotPreviewCallback()正在执行,并且相机试图在其自己的线程上调用onPreviewFrame(),但由于这也是一个同步方法,它会阻止等待getPicture()终止的过程,因为它需要回调来清除isDecoding。这看起来像是一个僵局

它无法调用onPreviewFrame,因为对象实例已锁定,因此摄影机线程在等待getPicture()完成时被阻止

我说得对吗? 我该如何解决这个问题?因此,我必须再次在PreviewFrame上通知IsDecode=false

非常感谢您的帮助

也投票支持这个,我会悬赏;)

mPreviewCallback.onPreviewFrame()中的notify()通知mPreviewCallback对象监视器,而getPicture()中的wait()在另一个对象监视器上等待-notify将永远不会释放wait()。您应该定义一个(最终)变量,该变量可以从两个对象访问,并显式地调用wait()和notify()。大概是这样的:

public final Object myMonitor = new Object();

public synchronized byte[] getPicture(int Width, int Height) {
    FrameWidth = Width;
    FrameHeight = Height;

    try {                     
        synchronized(myMonitor) {    
            while (!isPreviewOn) {
                myMonitor.wait();
            }
        }
        isDecoding = true;
        mAvailableFrame = false;

        c.setOneShotPreviewCallback(mPreviewCallback);                

        synchronized(myMonitor) {    
            while (isDecoding) {
                myMonitor.wait();
            }
        }
    }
    catch (Exception e) {   
        return null;
    }

    mAvailableFrame = false;

    return mCurrentFrame;
}

PreviewCallback mPreviewCallback = new PreviewCallback() {

    @Override
    public synchronized void onPreviewFrame(byte[] data, Camera camera) {
        int width = FrameWidth;
        int height = FrameHeight;

        // API 7
        int[] temp = new int[width*height];
        OutputStream out = new ByteArrayOutputStream();
        Bitmap bm = null;

        raw2jpg(temp, data, width, height);
        bm = Bitmap.createBitmap(temp, width, height, Bitmap.Config.RGB_565);
        bm.compress(CompressFormat.JPEG, 100, out);
        /*ref*/mCurrentFrame = ((ByteArrayOutputStream)out).toByteArray();
        mAvailableFrame = true;
        isDecoding = false;
        synchronized(myMonitor) {    
            myMonitor.notify();                   
        }
    }
};

我不知道您正在扩展的API,但在这次更改之后,可能不需要同步进程。此外,还不清楚是谁在设置ispreviewn。

您的第一次编辑似乎使用while(isDecoding)myMonitor.wait();。但是使用synchronized(myMonitor){myMonitor.notify();}它似乎会阻塞。尽管如此,使用while(正在编码)myMonitor.wait();我的应用程序检索nullpointerexception:S@XverhelstXnotify()和wait()必须使用synchronized()块进行保护,否则Java运行时将抛出
Java.lang.IllegalMonitorStateException:当前线程不是所有者
异常。在你的代码中加入一些调试日志,找出它在哪里阻塞,不工作。它在synchronized(myMonitor){while(isDecoding){myMonitor.wait();时阻塞,并且不会继续。并停留在该屏幕上。我无法按返回键,几秒钟后我得到:Activity…(应用程序中)没有响应。