java线程与输入优先级处理

两个线程先后等待控制台的输入,如何让后等待的线程先获取控制台输入的信息?

“Devil组”引证GPT后的撰写:

  • 在多线程应用程序中,可以使用线程同步机制来控制线程之间的执行顺序。为了让后等待的线程先获取控制台输入的信息,可以使用信号量(Semaphore)或者互斥锁(Mutex)来实现。

下面是使用互斥锁实现的示例代码:

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

std::mutex mtx;
std::string input_str;

void thread_func1()
{
    std::cout << "Thread 1 waiting for input..." << std::endl;

    // 等待获取互斥锁
    std::unique_lock<std::mutex> lock(mtx);

    // 获取控制台输入
    std::getline(std::cin, input_str);

    // 释放互斥锁
    lock.unlock();
}

void thread_func2()
{
    std::cout << "Thread 2 waiting for input..." << std::endl;

    // 等待获取互斥锁
    std::unique_lock<std::mutex> lock(mtx);

    // 等待输入线程1获取控制台输入
    while (input_str.empty())
    {
        lock.unlock(); // 先释放互斥锁
        std::this_thread::yield(); // 让出CPU
        lock.lock(); // 重新获取互斥锁
    }

    // 输出控制台输入
    std::cout << "Thread 2 got input: " << input_str << std::endl;
}

int main()
{
    // 创建两个线程
    std::thread t1(thread_func1);
    std::thread t2(thread_func2);

    // 等待两个线程结束
    t1.join();
    t2.join();

    return 0;
}


在上面的示例代码中,两个线程都等待控制台输入,但是只有先等待的线程1获取了互斥锁,可以获取控制台输入。线程1获取到控制台输入后,会释放互斥锁,然后线程2获取到互斥锁,尝试读取控制台输入。如果控制台输入为空,线程2会释放互斥锁,让出CPU,然后重新获取互斥锁,等待线程1获取控制台输入。直到线程1获取到控制台输入并释放互斥锁后,线程2才能读取控制台输入并输出。

通过互斥锁的使用,可以确保后等待的线程2先获取控制台输入的信息。

可以使用Java的wait()和notify()方法实现,参考:

import java.util.Scanner;

public class InputPriorityDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 创建两个线程并启动
        Thread thread1 = new Thread(() -> {
            synchronized (scanner) {
                try {
                    System.out.println("Thread 1 waiting for input...");
                    scanner.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 1 got input: " + scanner.nextLine());
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (scanner) {
                try {
                    System.out.println("Thread 2 waiting for input...");
                    scanner.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread 2 got input: " + scanner.nextLine());
            }
        });

        thread1.start();
        thread2.start();

        // 唤醒等待时间更长的线程
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (scanner) {
            System.out.println("Input something: ");
            scanner.notify();
        }

        // 唤醒另一个线程
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (scanner) {
            System.out.println("Input something again: ");
            scanner.notify();
        }
    }
}

请问你是要使用两个线程,当这两个线程有执行顺序,或者说第二个线程是第一个线程的输入,需要第一个输入完毕后,开启另一个线程来处理事件嘛。
这是个好主意,可以减少IO时间嘛,你可以在第二个线程中使用 join 让出线程,可以在第一个线程执行时调用第二个线程的join方法,这样第一个线程就必须等待第二个线程执行完毕。
当然这还可以实现第一个执行一半中途由第二个处理,处理完再返回给第一个线程执行,你只需要在适当代码位置调用即可。
比如下面这个例子。


    Thread t2 = new Thread(() -> {
        // 第二个线程做的事1

    });
    Thread t1 = new Thread(() -> {
        // 第一个线程做的事1
        try {
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       // 第一个线程做的事2
    });

有问题欢迎随时反馈。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^