为什么我的线程在从另一个线程调用notifyAll()后从wait()返回?

时间:2015-10-11 23:13:35

标签: java multithreading

我正在尝试创建两个线程来充当计数器。当一个线程递减其计数器时,它应该切换共享布尔标志字段的值,调用notifyAll()方法并从被调用的wait()方法释放另一个线程。逻辑字段用作避免死锁的手段,即当flag字段的值为true时,一个线程将调用wait()方法,而当flag字段的值为false时,另一个线程将调用它。您可以看到我运行从此类创建的线程的方式,以及下面的预期输出。问题是两个线程同时卡在wait()方法上,只有第一行输出通过。

预期产出:

Thread No.1 4
Thread No.2 4
Thread No.1 3
Thread No.2 3
Thread No.1 2
Thread No.2 2
Thread No.1 1
Thread No.2 1
Thread No.1 0
Thread No.2 0

实际输出:

Thread No.2 4

柜台类:

public class CounterThread implements Runnable {
    private long counter;
    private static int threadNumber = 0;
    private int index = 0;
    private static boolean flag = true;
    private boolean logic;

    public CounterThread(long counter, boolean logic) {

        index = ++threadNumber;
        this.counter = counter;
        this.logic = logic;
    }

    private synchronized void toggleFlag() {
        flag = !flag;
        notifyAll();
    }

    @Override
    public synchronized void run() {
        while (counter > 0) {
            while (flag==logic) {
                try {
                    wait();
                } catch (InterruptedException e) {

                }
            }
            counter--;
            System.out.println("Thread No. " + index + " " +counter);
            toggleFlag();
        }
     }
 }

我运行它的方式:

public final class CounterThreadRun {

    public static void main(String[] args) {
        CounterThread counter1 = new CounterThread(5, true);
        CounterThread counter2 = new CounterThread(5, false);
        Thread thread1 = new Thread(counter1);
        Thread thread2 = new Thread(counter2);
        thread1.start();
        thread2.start();
    }
}

1 个答案:

答案 0 :(得分:1)

因为您没有通知正在等待的线程。您只是通知当前线程,即您自己。您需要一个共享对象,可能是类中的#include <stdio.h> #include <stdlib.h> #include <string.h> #include <wchar.h> char *xlatlist[] = { "ba","aà", "ss", "aå", "AÅ", "yÿ", "XX", NULL }; // sanitize -- clean up utf8 sequences in a string void sanitize(char *dst,int uglyflg) // uglyflg -- 1=output unknown utf8's { char *src; char * const *xlatptr; const char *xlatstr; const char *utf8; int len; int foundflg; int chr; src = dst; while (1) { chr = *src; if (chr == 0) break; // skip translation loop if not utf-8 if ((chr & 0x80) == 0) { *dst++ = *src++; continue; } // try to match a translation foundflg = 0; for (xlatptr = xlatlist; ; ++xlatptr) { xlatstr = *xlatptr; if (xlatstr == NULL) break; utf8 = xlatstr + 1; len = strlen(utf8); if (strncmp(src,utf8,len) == 0) { *dst++ = xlatstr[0]; foundflg = 1; src += len; break; } } // utf8 translation found if (foundflg) continue; // NOTES: // (1) because of the optimization above, src _is_ pointing to a utf8 // but we have _no_ translation for it // (2) we can choose to skip it or just output it [and hope for the // best], but ... // (3) first, we need to get the length utf8 string, so we only // skip/output one utf8 string/char (e.g. we could have // back-to-back utf8 strings) // (4) for reference here, the utf8 encoding is: // byte 0: 11xxxxxx // byte 1: 10xxxxxx // output the first char of the unknown utf8 sequence if (uglyflg) *dst++ = *src; ++src; // output the remaining ones for (; ; ++src) { chr = *src; // EOS if (chr == 0) break; // back to ascii if ((chr & 0x80) == 0) break; // start of new utf8 string if ((chr & 0x40) != 0) break; // output the unknown utf8 secondary char if (uglyflg) *dst++ = chr; } } *dst = 0; } int main(int argc,char **argv) { char *z; --argc; ++argv; z = *argv; if (z == NULL) { printf("no argument provided\n"); exit(1); } printf("PRINT : %s\n",z); sanitize(z,0); printf("Sanitized string: %s\n",z); return 0; } ,用于staticwait()