java - 这个 "synchronized"可以工作吗?

标签 java multithreading


1.这里使用synchronized的方式是否正确?
2.一个线程访问randomScore时是否会被锁定,导致其他线程无法访问randomScore?
3.如果只有changeRandomScore()可以访问randomScore变量,并且只有一个线程可以访问changeRandomScore(),那么一次只有一个线程可以访问randomScore。这是对的吗?

    import java.*;


public class StudentThread extends Thread {
    int ID;  
    public static int randomScore;

      StudentThread(int i) {
          ID = i;
      }

      public void run() {
          changeRandomScore();

          System.out.println("in run");
      }
public synchronized void changeRandomScore() {
    randomScore = (int) (Math.random()*1000);
}
public static void main(String args[]) throws Exception {
    for (int i = 1;i< 10 ;i++) 
    {
            StudentThread student = new StudentThread(5);

            student.start(); 
            Thread.sleep(100);
            System.out.println(randomScore);
    }             
}  
}

最佳答案

您正在访问不同对象的同步方法内的静态变量。同步在这里没有实际效果,因为每个线程都使用自己的监视器(在本例中为线程对象)。对于共享变量,您也应该使用共享监视器。

这是一个正确同步的变体:

public class StudentThread extends Thread {
  int ID;  
  private static int randomScore;
  private static final Object scoreLock = new Object();

  StudentThread(int i) {
     ID = i;
  }

  public void run() {
     changeRandomScore();

     System.out.println("in run");
  }
  public void changeRandomScore() {
     int tmp = (int) (Math.random()*1000);
     // no need to synchronize the random()-call, too.
     synchronized(scoreLock) {
        randomScore = tmp;
     }
  }
  public static void main(String args[]) throws Exception {
      for (int i = 1;i< 10 ;i++) 
      {
          StudentThread student = new StudentThread(5);

          student.start(); 
          Thread.sleep(100);
          synchronized(scoreLock) {
              System.out.println(randomScore);
          }
      }             
  }  
}

不同的是,我们现在使用一个公共(public)锁对象(scoreLock)并将其用作同步块(synchronized block)的参数,并且我们还在读取分数的主方法中同步该对象.

或者,我们也可以声明方法 public static Synchronized void changeRandomScore() (这意味着它使用类对象作为监视器),并在主方法中在 StudentThread 上同步。类

是的,正如其他人所说:如果您想确保仅在正确同步的情况下访问变量,请不要将其设为public

关于java - 这个 "synchronized"可以工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4987716/

相关文章:

c - 我如何创建一个与 C 游戏同时工作的计时器?

java - 无法连接 VirtualBox VM 上的分析器 (JMC)

java - 变量为 final 时无法执行 try/catch/finally

java - Spark Java DataFrame 根据列求和并删除重复项

java - java中处理大量异步调用

java - 为什么 spring 只处理未经检查的异常

c# - 后台线程中的串行通信

c# - 线程优先级(如何获得固定顺序)

c# - 只有多个线程之一执行特定代码路径

java - 2 个 JVM 之间的低 CPU 使用率轮询架构