Thursday, 21 February 2008

two ways to synchronized in Java

The following two examples are the classic consumer/producer example of multithread programming. Here I used two ways of invoking synchronized to do such a job.

  1. synchronized method:

    import java.util.*;

    public class Que {

    /**
    * @param args
    */
    public static void main(String[] args) {

    mapQ q = new mapQ();

    new genQ(q);
    new conQ(q);
    }
    }

    ////////////////// the commodity Queue /////////////////
    class mapQ {

    String s;
    LinkedList que = new LinkedList();

    synchronized void put(String s) {

    if (que.size()>10)
    try {
    wait();
    }
    catch(InterruptedException e) {
    System.out.println("InterruptedException caught");
    }
    que.addLast(s);
    System.out.println("Put: " + s);
    notify();
    }

    synchronized String get() {

    if (que.isEmpty())
    try {
    wait();
    }
    catch (InterruptedException e) {
    System.out.println("InterruptedException caught");
    }
    String temps = (String) que.removeFirst();
    // System.out.println(que);
    System.out.println("Got: " + temps);
    notify();

    return temps;
    }
    }

    //////////////// producer /////////////////////
    class genQ implements Runnable {
    mapQ q;

    genQ(mapQ q) {
    this.q=q;
    new Thread(this, "Producer").start();
    }
    public void run() {
    int i=0;

    while(true) {
    int tempi = i++;
    q.put(Integer.toString(tempi));
    }
    }
    }

    /////////////// consumer ///////////////////////
    class conQ implements Runnable {
    mapQ q;

    conQ(mapQ q) {
    this.q=q;
    new Thread(this, "Consumer").start();
    }

    public void run() {
    while(true) {
    q.get();
    }
    }
    }





  2. synchronized block:

    import java.util.*;

    public class Que {

    /**
    * @param args
    */
    public static void main(String[] args) {

    mapQ q = new mapQ();

    new genQ(q);
    new conQ(q);
    }
    }

    ////////////////// the commodity Queue /////////////////
    class mapQ {

    String s;
    LinkedList que = new LinkedList();

    void put(String s) {
    synchronized(que){
    if (que.size()>10)
    try {
    que.wait();
    }
    catch(InterruptedException e) {
    System.out.println("InterruptedException caught");
    }
    System.out.println(que);
    que.addLast(s);
    // System.out.println("Put: " + s);
    que.notify();
    }
    }

    String get() {
    synchronized(que){
    if (que.isEmpty())
    try {
    que.wait();
    }
    catch (InterruptedException e) {
    System.out.println("InterruptedException caught");
    }
    String temps = (String) que.removeFirst();
    // System.out.println("Got: " + temps);
    que.notify();

    return temps;
    }
    }
    }

    //////////////// producer /////////////////////
    class genQ implements Runnable {
    mapQ q;

    genQ(mapQ q) {
    this.q=q;
    new Thread(this, "Producer").start();
    }
    public void run() {
    int i=0;

    while(true) {
    int tempi = i++;
    q.put(Integer.toString(tempi));
    }
    }
    }

    /////////////// consumer ///////////////////////
    class conQ implements Runnable {
    mapQ q;

    conQ(mapQ q) {
    this.q=q;
    new Thread(this, "Consumer").start();
    }

    public void run() {
    while(true) {
    q.get();
    }
    }
    }

###########################################################

P.S.:
The second choice is much clearer and flexible, but you should be careful how to call the wait() and notify(), which should be called by the synchronized object.

No comments:

My photo
London, United Kingdom
twitter.com/zhengxin

Facebook & Twitter