Joh*_*ohn 2 java multithreading
1.这里使用同步的方式是否正确?
2.当一个线程访问randomScore时,是否锁定了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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您在这里访问不同对象的synchronized-methods中的静态变量.这里的同步没有实际效果,因为每个线程都使用自己的监视器(在这种情况下是线程对象).对于共享变量,您也应该使用共享监视器.
这是一个正确同步的变体:
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
不同之处在于我们现在使用公共锁定对象(scoreLock)并将其用作synchronized块的参数,并且我们还在读取分数时在main方法中同步此对象.
或者,我们也可以声明方法public static synchronized void changeRandomScore()(这意味着它使用类对象作为监视器)并在main方法中同步StudentThread.class.
是的,正如其他人所说:如果你想确保只有正确同步才能访问变量,不要做到public.