class A {
synchronized void f() {//同步方法,执行时要获取到该对象的mornitor才do something,如果对象mornitor已被其他线程获取,则等待直到其他线程放弃再锁定该对象
//do something;
}
void g() {//非同步方法,执行时也要获得该对象的mornitor才do something,如果对象mornitor已被其他线程获取,则等待直到其他线程放弃再锁定
synchronized (this) {
//do something;
}
}
//synchronized不要写错了!上边如果do something完全一样的话,f和g等价,f其实是g的简写
}
synchronized void f() {//同步方法,执行时要获取到该对象的mornitor才do something,如果对象mornitor已被其他线程获取,则等待直到其他线程放弃再锁定该对象
//do something;
}
void g() {//非同步方法,执行时也要获得该对象的mornitor才do something,如果对象mornitor已被其他线程获取,则等待直到其他线程放弃再锁定
synchronized (this) {
//do something;
}
}
//synchronized不要写错了!上边如果do something完全一样的话,f和g等价,f其实是g的简写
}
import java.awt.*;
import java.applet.Applet;
class BounceThread extends Thread
{
private int incr=10;
private int yDir=1;
private int xDir=1;
private int sleepFor=100;
UsingWaitNotify applet;
public BounceThread(UsingWaitNotify applet)
{
this.applet=applet;
}
public void run()
{
Thread curThread=Thread.currentThread();
while(true)
{
synchronized(this)
{
if(applet.threadSuspended==true && applet.bounceThread==curThread)
{
try
{
curThread.wait();
}
catch(InterruptedException e)
{
System.out.println("InterrupedException occured!"+e);
}
}
}
applet.y+=(incr*yDir);
applet.x+=(incr*xDir);
applet.repaint();
if(applet.y-applet.radius<=0)
yDir=1;
else if(applet.y+applet.radius>=applet.getSize().height)
yDir=-1;
if(applet.x-applet.radius<=0)
xDir=1;
else if(applet.x+applet.radius>=applet.getSize().width)
xDir=-1;
try
{
sleep(sleepFor);
}
catch(InterruptedException e)
{
System.out.println("InterruptedException occured!"+e);
}
}
}
}
public class UsingWaitNotify extends Applet
{
public static int radius=20;
public static int x=30;
public static int y=30;
Thread bounceThread;
public boolean threadSuspended;
public void init()
{
bounceThread=new BounceThread(this);
bounceThread.start();
//System.out.println(threadSuspended);
}
public void start()
{
synchronized(bounceThread)
{
threadSuspended=false;
bounceThread.notify();
}
//System.out.println(threadSuspended);
}
public void stop()
{
threadSuspended=true;
System.out.println(threadSuspended);
}
public void destroy()
{
synchronized(bounceThread)
{
Thread t=bounceThread;
bounceThread=null;
t.notify();
}
//System.out.println(threadSuspended);
}
public void paint(Graphics g)
{
g.setColor(Color.blue);
g.drawOval(x-radius,y-radius,2*radius,2*radius);
}
}
在运行程序的时候,我本打算Applet进入start()方法的时候,线程终止执行。可是没有成功。我已经将threadSuspended变量置成true了,为什么在run方法中这个当前的线程并没有wait呢?谢谢那位大虾能帮我看一下哦!
在curThread.wait();前后边各加一句System.out.println("stop");看看怎样,如果确实打出stop来,目标就已经达到了
import java.applet.Applet;class BounceThread extends Thread {
private int incr = 10;
private int yDir = 1;
private int xDir = 1;
private int sleepFor = 100;
UsingWaitNotify applet;
public BounceThread(UsingWaitNotify applet) {
this.applet = applet;
}
public void run() {
Thread curThread = Thread.currentThread();
while (true) {
synchronized (this) {
if (applet.threadSuspended || curThread != applet.bounceThread) {
System.out.println(System.currentTimeMillis() / 1000);
try {
curThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() / 1000);
}
}
applet.y += (incr * yDir);
applet.x += (incr * xDir);
applet.repaint();
if (applet.y - applet.radius <= 0)
yDir = 1;
else if (applet.y + applet.radius >= applet.getSize().height)
yDir = -1;
if (applet.x - applet.radius <= 0)
xDir = 1;
else if (applet.x + applet.radius >= applet.getSize().width)
xDir = -1;
try {
sleep(sleepFor);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}public class UsingWaitNotify extends Applet {
public static int radius = 20;
public static int x = 30;
public static int y = 30;
Thread bounceThread;
public volatile boolean threadSuspended;
public void destroy() {
System.out.println("destroy.");
synchronized (bounceThread) {
Thread t = bounceThread;
bounceThread = null;
t.notify();
}
}
public void init() {
System.out.println("init.");
bounceThread = new BounceThread(this);
threadSuspended = true;
bounceThread.start();
}
public void paint(Graphics g) {
g.setColor(Color.blue);
g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
}
public void start() {
System.out.println("start.");
synchronized (bounceThread) {
threadSuspended = false;
bounceThread.notify();
}
}
public void stop() {
System.out.println("stop.");
threadSuspended = true;
}
}
/*
<HTML>
<HEAD>
<TITLE>UsingWaitNotify</TITLE>
</HEAD>
<BODY>
<H1>UsingWaitNotify</H1>
<p>
<A HREF=UsingWaitNotify.java>Source code for UsingWaitNotify</A>
<p>
<APPLET CODE=UsingWaitNotify.class WIDTH=250 HEIGHT=300>
</APPLET>
</BODY>
</HTML>
*/
1,applet的受控方式:浏览器打开页面时,依次执行applet.init()和applet.start();当浏览器被隐藏或失去焦点时,applet不受影响;当浏览器转向其他页面时,依次执行applet.stop()和applet.destroy(),当浏览器再次退回时,又重复执行applet.init()和applet.start()。再细查applet api,基本上也是这个意思!
2,线程确实陷入等待状态过,并能被唤醒。由于上述控制方式,该时间段极短。
3,实际执行时,线程大部分时间处于sleep(100)状态下,所以,浏览器转向其他页面时,applet被摧毁,所以,sleep()总是抛出异常。
4,用appletviewer来监控很难模拟上述过程。浏览器毕竟是applet最终的应用舞台。