Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java多线程-一个线程在另一个线程之前进入关键部分两次_Java_Multithreading_Thread Safety - Fatal编程技术网

Java多线程-一个线程在另一个线程之前进入关键部分两次

Java多线程-一个线程在另一个线程之前进入关键部分两次,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我有一个关键代码,包装在synchronized(this){}中 在日志中,我看到线程#1进入临界区,然后线程#2到达那里,等待,然后线程#1离开临界区,再次进入(2毫秒后)!甚至在其他线程进入之前 怎么可能呢? 线程#2不应该进入临界区吗 编辑: 正在添加我的类的一部分 @Service public class RequestService { Logger logger = LoggerFactory.getLogger(RequestService.class);

我有一个关键代码,包装在
synchronized(this){}

在日志中,我看到线程#1进入临界区,然后线程#2到达那里,等待,然后线程#1离开临界区,再次进入(2毫秒后)!甚至在其他线程进入之前

怎么可能呢? 线程#2不应该进入临界区吗

编辑:

正在添加我的类的一部分

@Service
public class RequestService {

    Logger logger = LoggerFactory.getLogger(RequestService.class);

    public HttpResponse executeRequest(HttpClient httpClient, HttpGet request) throws IOException, InterruptedException {
        logger.info("About to enter critical code");
        synchronized (this) {
            logger.info("executing http request");
            HttpResponse response = httpClient.execute(request);
            logger.info("got http response");
            return response;
        }
    }
}

同步块不“公平”。无法保证哪个线程在同步块可用时能够进入该块。

如果要引入公平性,可以使用

Lock lock = new ReentrantLock(true);
等待进入临界区的线程将以“公平”的顺序进入,即它们排队的顺序


默认的公平性策略是“不公平的”,因为公平性带来了大多数应用程序不需要的性能开销。

请显示更多代码。您的线程是否在一个类的不同实例上运行?然后,
这个
在不同的线程中是不同的,可以独立锁定。我想这是你的代码有问题。@rgetman-同一个类。春季单身服务。@OliverCharlesworth-我认为这很令人欣慰。附加我的代码。这是可能的,因为Java语言规范没有说这是不可能的。不能保证线程#2会在线程#1出现并再次到达同步块之前“醒来”,也不能保证线程会以尝试的相同顺序获得锁(即,Java
synchronized
块是不公平的)但我猜线程1离开临界区后,线程2得到了一些cpu。在它再次进入之前,为什么不进入关键部分?你在问为什么Java没有最大化争用。这是因为争论是不好的。我们希望在不切换线程的情况下完成尽可能多的工作,以便在相同数量的线程切换下完成更多的工作。交替显然是最糟糕的情况。如果你必须在一家商店买5件东西,在另一家商店买5件东西,你是从第一家商店买1件东西然后去另一家商店吗?@Nati-无论#2是否有cpu(不确定你是如何确定的),我的答案都不会改变。jvm完全可以拒绝线程2 15分钟,仅仅因为它不喜欢它。@jtahlborn,jvm是一个按照编程方式工作的程序。仅仅因为它不喜欢这是不公平的争论。我认为OP想知道JVM拾取线程的逻辑是什么,以及在什么情况下它将拾取相同的线程again@CharuKhurana-我用夸张的说法来说明一点:java规范不能保证同步块的公平性,因此jvm可以自由选择它喜欢的方式。jvm不是一个程序,它实际上是由多个供应商实现的许多程序,它们(希望)遵守规范。没有办法指定逻辑,因为每个jvm都有不同的逻辑。你唯一能指出的就是规格。