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…(应用程序中)没有响应。