我试图理解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)时才会看到它。
那么线程切换在没有睡眠的 for 循环中发生得更少吗?Java-JVM 是否有什么特别之处,它试图让 for-loop 将其作为“某种”原子执行(不完全但尽可能多?)?