注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

一路

To find the final symmetry & beauty

 
 
 

日志

 
 
 
 

Short Summary of Java’s wait() & notify() Thread synchronization usage[origin]  

2011-07-25 01:00:03|  分类: 学习笔记 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

    In java , there are mainly two methods to create new thread. First, inherit Thread class and call start method of subclass instance. Second and the most flexible way is to inherit Runnable interface and use this class to be parameter of Thread class constructor to make new thread. As java itself is designed to be a fully object oriented programming language. Its thread is also wrapped to be object oriented. Synchronized keyword must apply to an instance and use this instance to make thread synchronization. Java and affirm that only one thread can touch synchronized instance variable at the same time.

in thread one:

synchronized(var){

    do...

    do...

do...

}

 

in thread two:

synchronized (var){

    do...

    do...

    do...

}

In the above code sample, var references to the same object. If program is running in thread one synchronized block, then thread two can't go into synchronized block at this time, this other thread must idle for some time before var to out of synchronized block. Java virtual machine use variable instance var to make this affirmation. If program is running in thread two synchronized block, the condition is the same. Thread one can't go into synchronized block. OK, this synchronized block method is fairly simple to understand. Now we go to the usage of wait() and notify(). wait() & notify() are of the method of class Object. As all other classed are inherited from Object, so they are all have wait() & notify() method inherited from Object. Actually, Object also has method called notifyAll() which will be explained after the explanation of wait() and notify().

    wait() & notify() of variable instance must be used on instance within synchronized code block. Once one thread goes into synchronized block of one instance, we see this thread gained monitor of this instance, once this thread goes out of the synchronized code block of one instance, we say this thread release this instance's monitor. wait() makes one already gain monitor of instance thread to release monitor of this instance, as this thread releases this instance's monitor after calling wait() function on this instance, this thread can't continue execute because it is in a synchronized block but don't have instance variable's monitor. Now the monitor is not thrown away, it is put into the instance which is used to make thread synchronization. Now, other synchronized code blocks on this instance of other thread can take this thread's monitor and make execution in synchronized code block. In this other thread's synchronized code block, it can call nofity() method on the synchronization instance variable, this action will put monitor to the instance variable, attention should be taken here is that the origin idle thread can't continue to execute after call to notify(), as this executing thread where notify is called is not go out of synchronized code block. After this thread go out of synchronized block the origin idle thread can continue execution. If there are many idle thread wait on this same instance variable, which one can continue execution is chosen randomly, mostly depends on implementation of JVM. If there are no idle thread wait on this same instance variable, call notify() on instance variable has no effect.

    Now, I will make some explanation on synchronized method. Synchronized method is just a kind of shortcut of synchronized code block on reference of this. The following two function of class A are the same semantically.

class A{

    public synchronized void func1(){

        do...

        do...

    }

    public void func2(){

        synchronized(this){

        do...

        do...

        }

    }

}

As all class is inherited from Object, call wait() & notify() directly is call wait() & notify() on this. As said previously, there is one method called nofityAll() of Object, this method notify all other idle thread on this wait instance variable. If there are n thread wait on this instance variable, notifyAll() is the same as call nofity() n times.

The following is the code sample of classically thread synchronization problem- producer and consumer synchronization problem. Play with the code and you will know how to use synchronized code block and wait() & notify() mechanism of java

 

 

//Queue.java

//written by saturnman

//Queue implementation

public class Queue {

    //var

    int[] queue = null;

    int put_cursor = 0;

    int get_cursor = -1;

    boolean is_full = false;

    boolean is_empty = true;

    Queue(){

        this.queue = new int[20];

    }

    public synchronized void put(int productID){

        if(this.is_full==true){

            try {

                wait();

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

        this.queue[put_cursor%20] = productID;

        ++put_cursor;

        if(put_cursor%20==get_cursor%20){

            this.is_full = true;

            notify();

        }

        this.is_empty = false;

    }

    public synchronized int get(){

        if(this.is_empty==true){

            try {

                wait();

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

        ++get_cursor;

        if(this.get_cursor%20==this.put_cursor%20){

            this.is_empty=true;

            notify();

        }

        this.is_full = false;

        return this.queue[(get_cursor+19)%20];

    }

}

 

//Producer.java

//written by saturnman

//Producer implementation

public class Producer implements Runnable{

    //var

    private Queue q = null;

    private int productID = 1;

    public Producer(Queue q){

        this.q = q;

    }

    @Override

    public void run() {

        while(true){

            q.put(productID);

            ++productID;

            System.out.println("Produce product "+productID);

        }

    }

 

}

 

//Consumer.java

//written by saturnman

//Consumer implementation

public class Consumer implements Runnable{

    //var

    Queue q = null;

    public Consumer(Queue q){

        this.q = q;

    }

    @Override

    public void run() {

        while(true){

            ConsumeProduct(q.get());

 

        }

    }

    public void ConsumeProduct(int id){

        System.out.println("Consume product "+ id);

    }

 

}

 

//ThreadDemo.java

//written by saturnman

//Main implementation

public class ThreadDemo {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

        Queue q =new Queue();

        Producer p = new Producer(q);

        Consumer c = new Consumer(q);

        new Thread(p).start();

        new Thread(c).start();

    }

 

}

 

 

 

  评论这张
 
阅读(842)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017