gpt4 book ai didi

java - 该多线程代码的计数器输出

转载 作者:太空宇宙 更新时间:2023-11-04 06:09:31 26 4
gpt4 key购买 nike

我遇到了一个关于多线程编程的Java问题(请参见下面的代码)。基于this question并在 StackOverflow 上回答,我想我明白为什么会出现僵局。但我不明白的是,如果程序正常工作(即没有死锁),打印的 foo 值是多少?我认为它会是 20(线程 1 计数到 10,线程 2 计数到 10)。有人可以帮我解释一下这是怎么回事吗(最好以简单的方式,因为我对线程编程还是新手)?谢谢。

public class ThreadTest{

private static class ThreadOne extends Thread{
private ThreadTwo threadTwo;
public int foo = 0;

public void setThreadTwo(ThreadTwo th){
threadTwo = th;
}

public void run(){
try{
for(int i=0;i<10;i++) foo += i;

synchronized(this){this.notify();};

synchronized(threadTwo){threadTwo.wait();};

System.out.print("Foo: " + threadTwo.foo);
}catch(InterruptedException e){ e.printStackTrace();}
}
}

private static class ThreadTwo extends Thread{

private final ThreadOne threadOne;
public int foo = 0;

public ThreadTwo(ThreadOne th){
threadOne = th;
}

public void Run(){
try{
synchronized(threadOne){threadOne.wait();}
foo = threadOne.foo;

for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
}
catch(InterruptedException e){e.printStackTrace();}
}
}

public static void main(){
ThreadOne th1 = new ThreadOne();
ThreadTwo th2 = new ThreadTwo(th1);

th1.setThreadTwo(th2);

th1.start(); th2.start();
th1.join(); th2.join();
}
}

最佳答案

根据您的代码,如果没有死锁,foo 值将为 90(如果我没有计算错误)。因为您没有使用 foo += 1,而是使用了 foo += i

编辑:好的,一步一步来。

  1. foo = 0
  2. th1th2 启动。 th2 等待通知。 th1foo 增加到 45
  3. th1 通知并开始等待 th2th2 收到通知并开始将 foo 从 45 增加到 90
  4. th2 通知 th1th1 收到通知,并打印 th2.foo,即 90

编辑2:在没有并发修改的情况下从2个线程从0计数到90的正确方法是这样的

public class ThreadTest {
private static int counter = 0;

private static class Thread1 extends Thread {
final Object lock;

public Thread1(Object lock) {
this.lock = lock;
}

@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 10; i++)
counter += i;
}
}
}

private static class Thread2 extends Thread {
final Object lock;

public Thread2(Object lock) {
this.lock = lock;
}

@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 10; i++)
counter += i;
}
}
}

public static void main(String[] args) {
final Object lock = new Object();

final Thread th1 = new Thread1(lock);
final Thread th2 = new Thread2(lock);

th1.start();
th2.start();

try {
th1.join();
th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Counter: " + counter);
}
}

但是如果您被迫使用waitnotify,那就有点复杂了。使用该类的对象代替Object作为普通锁

class Locker {

private boolean isLocked = false;

public synchronized void lock() throws InterruptedException {
while (isLocked) wait();
isLocked = true;
}

public synchronized void unlock() {
isLocked = false;
notify();
}
}

run方法中我们这样:

@Override
public void run() {
try {
locker.lock();
for (int i = 0; i < 10; i++)
counter += i;
locker.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

关于java - 该多线程代码的计数器输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28907488/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com