java线程停止重新启动_使用通知/等待在Java中停止/重新启动线程

我正在开发针对Android 2.2+的简单视频录制应用程序,并且无法按预期方式使Timer线程正常工作。代码如下,所以步骤是:

当用户pres开始录制按钮时,开始录制并调用fightTimer.start()方法。

它调用timer.start()方法开始运行线程。 timer是fightTimer内部的线程对象

当用户点击停止按钮时,调用stopTimer方法stop()。在那里,我设置了一个标志stopTimer = true,这样就可以停止线程方法运行并调用timer.wait()方法,以便线程等待

当用户点击开始录制按钮时,再次调用fightTimer.start()方法。它调用线程timer.start(),因为计时器已经启动,但是它会抛出异常。

我捕获异常并调用fightTimer.restart()方法。此方法设置标志stopTimer我在步骤3中设置为true,所以现在我们有stopTimer = true。计时器线程仍在run()方法内部等待

然后它调用timer.notify()让计时器知道它不需要再等待并且可以继续运行

现在我期待计时器线程再次开始运行,但由于某种原因,此时执行跳转到调用notify()(restart())的同一方法的开头并设置标志stopTimer = false,然后尝试再次通知计时器线程。它引发运行时异常,并在那里结束。

我假设我对线程的整体同步的理解是不正确的,所以如果任何人都能指出我搞砸的地方那会很棒。下面是FightTimeris的代码,我甚至没有在logCat中获得任何输出信息。就像我说的任何帮助将不胜感激,因为我不明白为什么会发生这种情况,以及如何解决它。

public class FightTimer extends SurfaceView implements Runnable, SurfaceHolder.Callback {

public Thread timer;

public SurfaceHolder surfaceHolder;

public Canvas canvas;

public int counter=0;

public volatile boolean stopTimer=false;

public volatile boolean pauseTimer=false;

public FightTimer(Context context)

{

super(context);

surfaceHolder=getHolder();

// this is necessary to make surfaceview transparent

surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);

setZOrderOnTop(true);

surfaceHolder.addCallback(this);

timer=new Thread(this);

}

public void start()

{

try

{

timer.start();

}

catch(IllegalThreadStateException ex)

{

reStart();

}

}

public synchronized void reStart()

{

// here the method is executed twice as I described in step 7

// after notify() it actually jumps back to stopTimer=false again and then exits the function. Then outside of this object I catch RuntimeException

stopTimer=false;

timer.notify();

}

public synchronized void pause()

{

pauseTimer=true;

}

public synchronized void resume()

{

pauseTimer=false;

timer.notify();

}

public void stop()

{

stopTimer=true;

}

public void run() {

TimeWatch timeWatch=TimeWatch.start();

Paint paint=new Paint();

paint.setColor(Color.RED);

paint.setTypeface(Typeface.create("Arial",Typeface.NORMAL));

paint.setTextSize(20);

while(true)

{

// this is to pause timer

try

{

if(pauseTimer)

{

synchronized(timer) {

while(pauseTimer)

timer.wait();

}

// TODO heres the code should be executed when timer is resumed eg.

// maybe calculate how timer should count now as it wasn't counting for a while etc

}

} catch(InterruptedException ex)

{

}

// this is to pause timer

try

{

if(stopTimer)

{

synchronized(timer) {

while(stopTimer)

timer.wait();

}

// TODO heres the code should be executed when timer is restarted

// maybe reset timer completely etc

timeWatch.reset();

}

} catch(InterruptedException ex)

{

}

canvas=surfaceHolder.lockCanvas();

// canvas might not exists at this point as we might be in activitis onStop() callback and stopping preview

// etc. so we need to check if so then we exit run function

if(canvas==null) return;

//canvas.drawARGB(0,255,255,255);

canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);

long minutes=timeWatch.time(TimeUnit.SECONDS)/60;

canvas.drawText(counter+" "+minutes+":"+timeWatch.time(TimeUnit.SECONDS)%60,0,counter%60, paint);

counter++;

surfaceHolder.unlockCanvasAndPost(canvas);

}

}

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

// TODO Auto-generated method stub

//Toast.makeText(getContext(), "Surface Changed", Toast.LENGTH_LONG).show();

}

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

//timer.start();

}

public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub

// when surface is destroyed it means it cannot be displayed anymore and there is no canvas to draw

// meaning the run() method cannot draw anything and calls to surfaceHolder will throw exception

// so we need to stop thread here

// this will happen when activity is in onStop() callback and when is already invisible and we are going to

// remove the object anyway so we don't care what will happenn later and make it wait. All we need is stop

// run() from calling any other methods on canvas from surfaceHolder

Toast.makeText(getContext(), "Surface Destroyed", Toast.LENGTH_LONG).show();

}

public void setSurfaceHolder(SurfaceHolder surfaceHolder2) {

// TODO Auto-generated method stub

surfaceHolder=surfaceHolder2;

}

}请参阅restart()方法中的编辑注释。当重新启动()方法退出时,以下是调用堆栈。请让我知道是否需要更多信息。

DalvikVM[localhost:8754]

Thread [<1> main] (Suspended)

MyFirstAppActivity.startRecording(View) line: 271

Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]

Method.invoke(Object, Object...) line: 521

View$1.onClick(View) line: 2077

Button(View).performClick() line: 2461

View$PerformClick.run() line: 8888

ViewRoot(Handler).handleCallback(Message) line: 587

ViewRoot(Handler).dispatchMessage(Message) line: 92

Looper.loop() line: 123

ActivityThread.main(String[]) line: 4627

Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]

Method.invoke(Object, Object...) line: 521

ZygoteInit$MethodAndArgsCaller.run() line: 858

ZygoteInit.main(String[]) line: 616

NativeStart.main(String[]) line: not available [native method]

Thread [<7> Binder Thread #2] (Running)

Thread [<6> Binder Thread #1] (Running)

Thread [<8> Binder Thread #3] (Running)

Thread [<9> Thread-9] (Running)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值