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的简写
}

解决方案 »

  1.   

    我这里有一个这样的程序:
    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呢?谢谢那位大虾能帮我看一下哦!      
      

  2.   

    也许露出一角的时候start()又启动了呢!
    在curThread.wait();前后边各加一句System.out.println("stop");看看怎样,如果确实打出stop来,目标就已经达到了
      

  3.   

    谢谢这位高人热情相住,但是照你的做法,在执行程序的时候,还是没能打印出stop,你8能帮我看看这到底是出了什么事了呢?
      

  4.   

    synchronized块跟的对象是块中要用到的方法的类实例
      

  5.   

    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 || 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>
    */
      

  6.   

    这个程序经过修改,除去有嫌疑的地方,得到了一些结论:
    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最终的应用舞台。