首页 新闻 会员 周边 捐助

A,B两个线程使用同一个Condition对象时,A线程唤醒等待中的B之后必须进入等待吗?

0
悬赏园豆:50 [待解决问题]

我是一个JAVA新手,最近在做一道多线程的题,题目:
使用A线程打印1-52,B线程打印A-Z,要求按照12A34B56C....5152Z的顺序进行交替打印。

我在编程的时候遇到两个问题。
问题1:
当A线程打印完52后,唤醒B线程的语句 condition.signal(); 没有发挥作用,导致Z打印不出来。然后我在 condition.signal(); 这个语句后边跟了一个 condition.await(); 就正常打印出Z了。 因此我想问下,是不是执行中的线程唤醒同一个Condition对象下等待的线程之后,自己必须进入等待状态呀?这是为什么呢?

问题2:
我的这段代码在Eclipse执行完毕之后,Terminate按钮还是处于红色状态的,说明程序还在等待中,这是为什么啊?

问题补充:

源代码如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class NumThread extends Thread {
PrinterClass pc;

NumThread (PrinterClass pc){
    this.pc = pc;
}

public void run() {
    while(PrinterClass.number < 53) {
        pc.printMethod(1);
        
    }
    
}

}

class ChapThread extends Thread {
PrinterClass pc;

ChapThread (PrinterClass pc){
    this.pc = pc;
}

public void run() {
    while (PrinterClass.chapter < 26) {
    pc.printMethod('p');
    
    }
}

}

class PrinterClass {
public static int number = 1;
public static int chapter = 0;
private static int flag = 0;
private final Lock printLock = new ReentrantLock();
private Condition condition = printLock.newCondition();

public void printMethod (Object printContents) {
        printLock.lock();
        if (flag ==0 || flag == 1) {
            if (printContents instanceof Integer) {
            System.out.println(number);
            flag ++;
            number++;
            if (number > 52) {
                
                try {
                condition.signal();
                condition.await();
                }
                catch (Exception e) {
                    
                }
                finally{
                    printLock.unlock();
                }
                
            }
            printLock.unlock();
            }
            if (printContents instanceof Character) {
                try {
                    condition.signal();
                    condition.await();
                }
                catch (Exception e) {
                    printLock.unlock();
                }
            }
        }
        else if (flag == 2) {
            if (printContents instanceof Character) {
            System.out.println((char)(65+chapter));
            flag = 0;
            chapter++;
        
            
            printLock.unlock();
            
            }
            if (printContents instanceof Integer) {
                try {
                    condition.signal();
                    condition.await();
                }
                catch (Exception e) {
                    printLock.unlock();
                }
            }
        }
        
}

}

public class MultiThread_ReentrantLock {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    PrinterClass pc = new PrinterClass();
     NumThread nt = new NumThread(pc);
     nt.start();
     new ChapThread(pc).start();
    
}

}

日进一卒的主页 日进一卒 | 初学一级 | 园豆:154
提问于:2020-02-17 16:19
< >
分享
所有回答(1)
0

感觉你的实现思路就有问题,可以参考我写的demo
附上我的代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

namespace its {

std::mutex mtx;
std::condition_variable cv;
int index = 1;

void print_number() {
    std::unique_lock<std::mutex> lck(mtx);
    for (int i = 1; i <= 52; i++) {
        if (index % 3 == 0) {
            cv.wait(lck);
        }
        std::cout << i << " ";
        index++;
        cv.notify_all();
    }
}

void print_alphabet() {
    std::unique_lock<std::mutex> lck(mtx);
    for (char i = 'A'; i <= 'Z'; i++) {
        if (index % 3 != 0) {
            cv.wait(lck);
        }
        std::cout << i << std::endl;
        index++;
        cv.notify_all();
    }
}
}

int main() {
    std::thread threads[2];
    threads[0] = std::thread(its::print_number);
    threads[1] = std::thread(its::print_alphabet);

    std::cout << "2 threads ready to race...\n";

    for (auto &th : threads)
        th.join();

    return 0;
}
wengle | 园豆:567 (小虾三级) | 2020-02-24 11:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册