gpt4 book ai didi

java:为什么两个线程不并行执行

转载 作者:搜寻专家 更新时间:2023-11-01 03:32:19 27 4
gpt4 key购买 nike

我正在尝试理解 java 中的内在锁。我有一个程序,我在其中启动 2 个线程,这些线程将循环并在同一个对象上调用同步方法。我希望两个线程并行执行,但看起来它是按顺序执行的。

如果我在循环中引休眠眠,那么它们会以随机顺序执行 [如我所料]

public class Synchronized {

private int valueM;

public Synchronized( int value) {
valueM = value;
}

synchronized
public void one() throws InterruptedException
{
System.out.println("Object[" + valueM + "] executing one");
Thread.sleep(100); //For case 2: comment it out
System.out.println("Object[" + valueM + "] completed one");
}

synchronized
public void two() throws InterruptedException
{
System.out.println("Object[" + valueM + "] executing two");
Thread.sleep(100); //For case 2: comment it out
System.out.println("Object[" + valueM + "] completed two");
}

}

测试代码:

@org.junit.jupiter.api.Test
void test_sync() throws InterruptedException
{
Synchronized obj = new Synchronized(1);

Runnable task_one = new Runnable() {
public void run() {
for (int i=0 ; i<10; i++)
{
try {
obj.one();
//Thread.sleep(100); //For case 2: uncomment it out
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};

Runnable task_two = new Runnable() {
public void run() {
for (int i=0 ; i<10; i++)
{
try {
obj.two();
//Thread.sleep(100); //For case 2: uncomment it out
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};

Thread t1 = new Thread(task_one);
Thread t2 = new Thread(task_two);

t1.start();
t2.start();

t1.join();
t2.join();
}

输出:

Case 1: output:
Object[1] executing one
Object[1] completed one
...10times
Object[1] executing two
Object[1] completed two
...10times

Case 2: output: random order
Object[1] executing one
Object[1] completed one
Object[1] executing two
Object[1] completed two
...

更新:原始问题已解决。看起来即使在情况 1 中也是随机的,但我只有在加载更多迭代 (30K) 时才会看到它。

所以线程切换在没有 hibernate 的 for 循环中发生得更少? Java-JVM 是否有特殊之处,它试图让 for 循环将其作为“一种”原子执行(不是完全但尽可能多?)?

最佳答案

intrinsic 锁(synchronized 关键字)被认为是“不公平的”,这意味着不能保证锁的获取率在竞争线程中是相同的。

众所周知,释放锁的线程通常更有可能再次获取锁,从而导致您遇到的问题。

如果您希望您的线程具有相似的获取可能性(公平性),您可以使用像 ReentrantLock 这样的显式锁。确保使用可选的 boolean 参数将其设置为 true

ReentrantLock(boolean fair)

然后就可以这样使用了

class X {
private final ReentrantLock lock = new ReentrantLock(true);

public void m() {
lock.lock();
try {
// method body
} finally {
lock.unlock()
}
}
}

关于java:为什么两个线程不并行执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46843971/

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