java同步和饥饿

时间:2013-10-01 05:19:07

标签: java multithreading synchronization

我已经制作了一个程序并希望输出如下:

一个 1 一个 乙 2 b C 3 C ...

电子 五 ë

这是我的代码我认为我正在获得饥饿问题PLZ帮助我

class Product {
    static boolean flag1, flag2, flag3;

    synchronized void printLwrAlpha(char value) {
        // System.out.println(flag3+": inside lwr_alpha");
        if (!flag3)
            try {
                wait();
            } catch (Exception ex) {
                System.out.println(ex);
            }
        System.out.println(value);
        flag3 = false;
        flag1 = false;
        System.out.println("before notify");
        notify();
        System.out.println("after notify");
    }

    synchronized void printUprAlpha(char n) {
        // System.out.println(flag1+": inside upr_alpha");
        if (flag1)
            try {
                wait();
            } catch (Exception e) {
                System.out.println(e);
            }
        System.out.println(n);
        // System.out.println(num);
        flag1 = true;
        flag2 = true;
        notify();
    }

    synchronized void printNum(int num) {
        // System.out.println(flag2+": inside num");
        if (!flag2)
            try {
                wait();
            } catch (Exception e) {
                System.out.println(e);
            }
        // System.out.println(n);
        System.out.println(num);
        flag2 = false;
        flag3 = true;
        notify();
    }
}

class PrintNum implements Runnable {
    Product p;

    PrintNum(Product p) {
        this.p = p;
        new Thread(this, "Producer").start();
        try {
            Thread.sleep(1000);
        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

    public void run() {
        for (int i = 1; i <= 5; i++)
            p.printNum(i);
    }
}

class PrintLwrAlpha implements Runnable {
    Product p;
    static char ch = 'a';

    PrintLwrAlpha(Product p) {
        this.p = p;
        new Thread(this, "Producer").start();
        try {
            Thread.sleep(1000);
        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            char c = (char) (ch + (i - 1));
            p.printLwrAlpha(c);
        }
    }

}

class PrintUprAlpha implements Runnable {
    Product p;
    static char ch = 'A';

    PrintUprAlpha(Product p) {
        this.p = p;
        new Thread(this, "Producer").start();
        try {
            Thread.sleep(1000);

        } catch (Exception ex) {
            System.out.println(ex);
        }
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            char c = (char) (ch + (i - 1));
            p.printUprAlpha(c);
        }
    }
}

public class MainClass1 {
    public static void main(String ar[]) {
        Product p = new Product();
        new PrintNum(p);
        new PrintUprAlpha(p);
        new PrintLwrAlpha(p);
    }

}

我得到了这个输出:

运行: 一个 1 乙 2 C 3 d 4 Ë 五 一个 在通知之前 通知后

我想在这个节目进入饥饿之后

2 个答案:

答案 0 :(得分:0)

替换所有的ifs,例如

if (!flag3)

with while循环

while (!flag3)

答案 1 :(得分:0)

如果我理解正确您的问题是您尝试使用具有多个线程的单个等待对象。 wait / notify的常见场景如下:一个线程正在等待资源变为可用,而第二个线程生成资源并通知第一个线程。 在代码中它可能如下所示:

class ResourceFactory {
     public synchronized void produce()
     {
         // make the resource available
         obj.notify();
     }

     public synchronized void consume()
     {
          if( /* resource is not available */ ) {
              obj.wait();
          }
          // do something with resource
     }
}

当多个线程试图在单个对象上等待时,问题在于实现在通知调用之后将唤醒哪个线程。我认为你应该制作3个不同的对象并做这样的事情:

// thread 1
obj1.wait();
obj2.notify()

// thread 2
obj2.wait();
obj3.notify()

// thread 3
obj3.wait();
obj1.notify()

小心并尽量不要使代码死锁。

最后你的代码。尽管有标志,但前两个线程正在等待并相互唤醒。当第三个线程被唤醒时,没有线程通知它。所以这是一个经典的僵局。