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

我试图理解
java中的内在锁.我有一个程序,我启动2个线程,它将循环通过并在同一个对象上调用synchronized方法.我希望两个线程并行执行,但看起来它是按顺序执行的.

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

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循环将其作为“种类”原子(不完全但尽可能多?)执行?

最佳答案 内部锁定(synchronized关键字)被认为是“不公平”,这意味着无法保证锁定的获取率在竞争线程中是相同的.

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

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

ReentrantLock(boolean fair)

然后你就可以这样使用它

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

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