当前位置: 首页 > 面试题库 >

Java线程结果不一致

邴兴为
2023-03-14
问题内容

我有一个实现可运行的线程类和一个int计数器作为实例变量。两种同步方法add和sub。当我以某种方式运行测试类时,它几次会输出错误的结果。据我了解,当方法同步时,整个对象将被锁定以供其他线程访问,这种逻辑每次我们都应该获得相同的结果正确吗?事实并非如此。我想念什么吗?

我的机器是Windows 7、64位。

 public class ThreadClass implements Runnable {

        int counter = 0;

        @Override
        public void run() {
            add();
            sub();
        }

        public synchronized void add() {
            System.out.println("ADD counter" + (counter = counter + 1));
        }

        public synchronized void sub() {
            System.out.println("SUB counter" + (counter = counter - 1));
        }
    }

测试类

public class ThreadTest {

    public static void main(String args[]) {
        ThreadClass tc = new ThreadClass();
        Thread tc0 = new Thread(tc);
        tc0.start();
        tc0.setPriority(Thread.MAX_PRIORITY);
        Thread tc1 = new Thread(tc);
        tc1.start();
        tc1.setPriority(Thread.NORM_PRIORITY);
        Thread tc2 = new Thread(tc);
        tc2.start();
        tc2.setPriority(Thread.MIN_PRIORITY);
    }
}

结果

ADD counter1
ADD counter2
SUB counter1
SUB counter0
ADD counter1
SUB counter0

注意: 您可能需要进行几次运行才能产生这种不一致。


问题答案:

同步确实意味着所有线程将在等待进入同步块之前阻塞等待获取锁。对象上只有一个线程可以锁定,因此add()or sub()方法中只能有一个线程。

但是,这并不意味着有关线程的顺序。您正在启动三个线程-唯一的保证是,通过立即运行addor
sub方法,它们不会互相sto脚。线程1可以调用add(),然后线程3可以调用add(),然后线程2可以调用add(),然后它们都可以调用sub()。或者他们都可以打电话add(),然后sub()每个人都打电话。或任何混合-
唯一的要求是每个线程都在调用add()之前调用,sub()并且永远不会调用任何两个线程,add()或者sub()在该方法中同时调用另一个线程。

撇开它:在某些情况下,它可能是不好的形式this,因为它是公共的,因此通常无法同步。通常更喜欢使用内部私有Object锁来锁定,这样其他任何调用者都无法获得您的锁定并违反您设计的任何锁定策略。



 类似资料:
  • 问题内容: 我有以下对象: 我在以下使用它: 现在,树形图用于一个称为的类中,用于存储图形中当前存在的节点以及它们的边集(来自class )。我的问题是当我尝试执行时: 我有时会得到以下信息: 哈希码:true等于:true包含: false N:foo X:foo比较数:0 有人知道我在做什么错吗?我对这一切仍然是陌生的,所以如果我忽略了一些简单的事情,我会事先道歉(我知道这并不重要,但我想我会

  • (线程:持续时间)-->(1:16)、(2,3:32)、(4,5,6,7:47)、(8,9:31)...(17,18,19,20:16) 该项目有2个项目: 工人阶层: 主类:

  • 首先,我不太熟悉CompletableFuture。我试图做的是通过CompletableFuture从数据库中检索数据,然后对结果进行处理。使用CompletableFuture#join/get处理数据会阻塞线程。 请注意,我试图不在一个单独的线程上运行上面的代码部分。有没有什么好的办法来做到这个不堵?我很确定我的代码有问题(可能是GetOfflinePlayerAsync?)我真的不知道该怎

  • 如何测试线程?A有我的课,我想测试一下。我知道名单上有什么

  • 我有自己的方法。net项目来加密密码 我的任务是将此方法转换为java,但在java中,我没有得到与该方法相同的结果。网络版 我的java代码是 加密“1”的结果是: 而java是 你能帮我解决这个问题吗?

  • 我正在为这个问题寻找一个干净的设计/解决方案:我有两个线程,可以运行用户想要的时间,但最终会在用户发出停止命令时停止。然而,如果其中一个线程突然终止(例如,由于运行时异常),我想停止另一个线程。 现在,这两个线程都执行一个(因此,当我说“stop a thread”时,我的意思是对实例调用一个stop()方法),我想的是避免使用线程(thread类),并使用interface,然后将这两个Runn