当前位置: 首页 > 知识库问答 >
问题:

java 多线程的一个问题 ?

易祯
2023-12-22
public class Demo01{    public static void main(String[] args) throws InterruptedException {        var q = new TaskQueue();        var ts = new ArrayList<Thread>();        for (int i=0; i<5; i++) {            var t = new Thread() {                public void run() {                    // 执行task:                    while (true) {                        try {                            String s = q.getTask();                            System.out.println("execute task: " + s);                        } catch (InterruptedException e) {                            return;                        }                    }                }            };            t.start();            ts.add(t);        }        var add = new Thread(() -> {            for (int i=0; i<10; i++) {                // 放入task:                String s = "t-" + Math.random();                System.out.println("add task: " + s);                q.addTask(s);                try { Thread.sleep(100); } catch(InterruptedException e) {}            }        });        add.start();        add.join();        Thread.sleep(100);        for (var t : ts) {            t.interrupt();        }    }}class TaskQueue {    Queue<String> queue = new LinkedList<>();    public synchronized void addTask(String s) {        this.queue.add(s);        this.notifyAll();    }    public synchronized String getTask() throws InterruptedException {        while (queue.isEmpty()) {            this.wait();        }        return queue.remove();    }}

教程这样说道:“内部调用了this.notifyAll()而不是this.notify(),使用notifyAll()将唤醒所有当前正在this锁等待的线程,而notify()只会唤醒其中一个(具体哪个依赖操作系统,有一定的随机性)。这是因为可能有多个线程正在getTask()方法内部的wait()中等待” 。
我有点疑惑的一句话是 “可能有多个线程正在getTask()方法内部的wait()中等待” , 比如A B C 三个线程,A线程进入了 getTask()方法 , 那么 B 和 C 方法就必须在外面等着啊 。

共有3个答案

西门骁
2023-12-22
可能有多个线程正在getTask()方法内部的wait()中等待

我认为正确的表述应该是

可能有多个线程正在等待当前线程执行getTask()方法内部的wait()方法

因为当前线程执行完wait()方法后,会释放当前的线程锁,其他线程就会去争夺了

毛景曜
2023-12-22

wait 会释放锁。

农飞翔
2023-12-22

比如A B C 三个线程,A线程进入了 getTask()方法 , 那么 B 和 C 方法就必须在外面等着,A调用this.wait(),A就加入到this的等待房间,并释放锁了,B和C有个就进来了,然后重复A的过程,就这样他们三个都进到 this的等待房间了,addTask中有线程调用this.notifyAll(),那么就去房间里面去叫醒ABC三个线程他们先抢占锁,抢占到了就从this.wait()继续执行。

 类似资料:
  • 如图所示, 位置 2 和位置3 为什么可以访问 位置1 (也就是主线程)的 point 局部变量 ? 毕竟 位置 2 和位置3 是另外两个线程啊 !! 当我加上 第10行代码后,thread1 和 thead2 中都不能访问主线程中的point 了。我知道这是内部类的“事实最终变量” 的限制。 如下图所示,就是我不理解的地方。(在 “栈内存” 层面) 我的猜测:之所以 thread1 和 trea

  • 1):单线程应用程序只会在用户的CPU上使用1个线程吗?提供更多的线程会使用多个CPU内核吗?如果声明的线程比用户的CPU多,会发生什么?

  • 这个方法是返回对当前正在执行的线程对象的引用。 但是,如果有两个线程在并行执行呢 ? 难道返回两个线程对象吗 ?

  • 面试问题 比如说,我们有一个在Employee表中有200万条记录的表,我们需要削减每个员工10%的工资(需要做一些处理),然后将其保存回collection。你怎样才能有效地做到这一点。 我问他,我们可以使用executor框架来创建多个线程,这些线程可以从表中获取值,然后我们可以处理并将其保存到列表中。 然后他问我,你将如何检查一个记录是否已经被处理,我不知道(如何做)。 甚至我也不确定我是否

  • 以下是问题陈述: 编写一个java程序,使用线程计算前25个素数,并计算前50个斐波那契数。将计算斐波那契数的线程的优先级设置为8,将另一个设置为5。在计算了30个斐波那契数之后,让这个线程进入睡眠状态,开始计算素数。计算完25个素数后,继续斐波那契数计算。 我的代码: 我本以为当斐波那契线停止时,其余的素数会被打印出来,但那没有发生,这背后的原因可能是什么?

  • 我对连接池的理解是;如果connectionstring完全相同,那么我们重用该连接,而不是建立新的连接。 我的问题是,我正在为并行处理创建许多线程。在这个“虚拟”程序中,我创建了500个线程,并让线程池函数处理这些线程。 步骤是: > < li> 每个线程在SQL中创建一个更新表。(说明更新的时间戳) 然后线程Hibernate1到10秒(随机)。 最后,线程在 SQL 中进行另一次更新(说明结