本帖最后由 黄小贝 于 2013-10-25 00:18 编辑
好吧,我觉得你应该事先谷歌才来问问题的,这样来混技术分不合适~让专业的来给你分析
Synchronization is achieved using monitors. Every object can have a monitor associated with it, so any object can synchronize blocks. Before a synchronized block can be entered, a thread needs to gain ownership of the monitor for that block. Once the thread has gained ownership of the monitor, no other thread synchronized on the same monitor can gain entry to that block (or any other block or method synchronized on the same monitor). The thread owning the monitor gets to execute all the statements in the block, and then automatically releases ownership of the monitor on exiting the block. At that point, another thread waiting to enter the block can acquire ownership of the monitor.
首先你需要明白synchronized的原理,它是由monitors实现的,每个对象都有一个monitors,所以synchronized()的括号里面可以填任意对象,当一个线程试图进入一个synchronized代码块的时候,必须得到这个代码块的monitors,一旦有一个线程得到了这个代码块的monitors后,其他所有在同一monitors下的线程都必须等待,获得monitors的线程执行完代码后会自动释放monitors的所有权,好让其他线程进入
很好,概念扯完了,给你看一个例子
让我能完成一个小例子,两个线程,对 n 进行操作,一个从从 1 打印到5 一个从 5打印到 1- package com.yellow.chapteOne;
- public class Test {
- private static int n = 0;
- private static boolean flag = true;
- public static void main(String[] args) {
- final Object lock = new Object();
- Thread thread1 = new Thread(new Runnable() {
- @Override
- public void run() {
- synchronized (lock) {
- while (true) {
- if (flag != true) {
- try {
- lock.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- for (int i = 0; i < 5; i++) {
- System.out.println(n++);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- flag = false;
- lock.notify();
- }
- }
- }
- });
-
- Thread thread2 = new Thread(new Runnable() {
- @Override
- public void run() {
- synchronized (lock) {
- while (true) {
- if (flag != false) {
- try {
- lock.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- for (int i = 0; i < 5; i++) {
- System.out.println(n--);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- flag = true;
- lock.notify();
- }
- }
- }
- });
-
- thread1.start();
- thread2.start();
- }
- }
复制代码 这个例子里面的synchronized的对象是final Object lock = new Object(); 因为两段synchronized代码都在lock的monitors下,so,他们不可能能够同时执行
现在就到了wait和notify的作用了,看看源码注释
wait()的- /**
- * The current thread must own this object's monitor. The thread 当前线程必须拥有这个对象的monitor
- * releases ownership of this monitor and waits until another thread 并且释放自己对monitor的所属权
- * notifies threads waiting on this object's monitor to wake up 直到另一个线程执行notifies 或者 notifyAll
- * either through a call to the <code>notify</code> method or the
- * <code>notifyAll</code> method. The thread then waits until it can 这个线程会一直等待直到重新获得monitor的所有权然后继续执行
- * re-obtain ownership of the monitor and resumes execution.
- * <p>
- * As in the one argument version, interrupts and spurious wakeups are
- * possible, and this method should always be used in a loop: 正是因为执行这个方法的前提是必须获得monitor
复制代码 notify()的- /**
- * Wakes up a single thread that is waiting on this object's 唤醒其他在等这个对象的monitor的线程
- * monitor. If any threads are waiting on this object, one of them 如果有很多线程都在等这个monitor,随机选一个~~
- * is chosen to be awakened. The choice is arbitrary and occurs at 好吧,所以这很不科学,想唤醒所有的线程,请用notifyAll
- * the discretion of the implementation. A thread waits on an object's
- * monitor by calling one of the <code>wait</code> methods.
- * <p>
- * The awakened thread will not be able to proceed until the current
- * thread relinquishes the lock on this object. The awakened thread will
- * compete in the usual manner with any other threads that might be
- * actively competing to synchronize on this object; for example, the
- * awakened thread enjoys no reliable privilege or disadvantage in being
- * the next thread to lock this object.
- * <p>
- * This method should only be called by a thread that is the owner
- * of this object's monitor. A thread becomes the owner of the
- * object's monitor in one of three ways:
- * <ul>
- * <li>By executing a synchronized instance method of that object.
- * <li>By executing the body of a <code>synchronized</code> statement
- * that synchronizes on the object.
- * <li>For objects of type <code>Class,</code> by executing a
- * synchronized static method of that class.
- * </ul>
- * <p>
- * Only one thread at a time can own an object's monitor.
- *
- * @exception IllegalMonitorStateException if the current thread is not
- * the owner of this object's monitor.
- * @see java.lang.Object#notifyAll()
- * @see java.lang.Object#wait()
- */
复制代码 至于 sleep() 那只是当当前执行的线程停止...- /**
- * Causes the currently executing thread to sleep (temporarily cease
- * execution) for the specified number of milliseconds, subject to
- * the precision and accuracy of system timers and schedulers. The thread 没有失去monitors的所有权
- * does not lose ownership of any monitors.
- *
- * @param millis the length of time to sleep in milliseconds.
- * @exception InterruptedException if any thread has interrupted
- * the current thread. The <i>interrupted status</i> of the
- * current thread is cleared when this exception is thrown.
- * @see Object#notify()
- */
- public static native void sleep(long millis) throws InterruptedException;
复制代码 好啦~~总结一下,sleep是停止当前线程,没有失去monitors,wait是释放monitors让其他在同一个monitors下的线程有机会执行然后进行等待,notify是去线程执行完了去唤醒其他在等待的线程
现在懂了吧~~版主不加分我就再也不相信爱情了
|