Java 为什么这个线程允许另一个线程访问它的同步方法?
我有以下代码。我期望一个线程完全执行其同步方法,然后允许另一个线程访问同一方法。然而,情况并非如此Java 为什么这个线程允许另一个线程访问它的同步方法?,java,Java,我有以下代码。我期望一个线程完全执行其同步方法,然后允许另一个线程访问同一方法。然而,情况并非如此 public class Threads { /** * @param args */ public static void main(String[] args) { //Thread Th = new Threads(); Thread th = new Thread (new thread1 ()); t
public class Threads {
/**
* @param args
*/
public static void main(String[] args) {
//Thread Th = new Threads();
Thread th = new Thread (new thread1 ());
th.start();
Thread th1 = new Thread (new thread1 ());
th1.start();
}
}
class thread1 implements Runnable{
String name = "vimal";
public void run() {
System.out.println("Runnable "+this.name);
setNAme("Manish");
}
public synchronized void setNAme(String name){
try {
System.out.println("Thread "+Thread.currentThread().getName());
wait(1000);
this.name = name;
System.out.println("Name "+this.name);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我有一个输出作为
Runnable vimal
Thread Thread-0
Runnable vimal
Thread Thread-1
Name Manish
Name Manish
这里的synchronized有什么用?我如何使我的方法在其他人访问它之前完全运行?您必须删除对等待(1000)的调用。看起来您真正想要的是调用线程。sleep(1000),如果您只是想暂停当前线程,这不会释放任何监视器的所有权 从对象的javadoc.wait() 此方法导致当前线程(称为T)将自身置于 为该对象设置的等待,然后放弃任何和所有 此对象上的同步声明。线程T将被禁用 线程调度的目的和休眠,直到四件事之一 发生:
- 另一个线程调用这个对象的notify方法,而线程T恰好被任意选择为要调用的线程 觉醒了
- 其他一些线程为此对象调用notifyAll方法
- 另一个线程中断了线程T
- 指定的实时时间已过,或多或少。但是,如果超时为零,则不考虑实时性 线程只需等待通知李>
更新:如其他答案所述,您没有在同一对象上同步。一旦你这样做了,由于我提到的问题,你仍然会遭受相同的输出。您需要修复这两个问题以获得所需的结果。您必须取消对等待(1000)的调用。看起来您真正想要的是调用线程。sleep(1000),如果您只是想暂停当前线程,这不会释放任何监视器的所有权 从对象的javadoc.wait() 此方法导致当前线程(称为T)将自身置于 为该对象设置的等待,然后放弃任何和所有 此对象上的同步声明。线程T将被禁用 线程调度的目的和休眠,直到四件事之一 发生:
- 另一个线程调用这个对象的notify方法,而线程T恰好被任意选择为要调用的线程 觉醒了
- 其他一些线程为此对象调用notifyAll方法
- 另一个线程中断了线程T
- 指定的实时时间已过,或多或少。但是,如果超时为零,则不考虑实时性 线程只需等待通知李>
更新:如其他答案所述,您没有在同一对象上同步。一旦你这样做了,由于我提到的问题,你仍然会遭受相同的输出。您将需要修复这两个问题以获得所需的结果。
synchronized
在这里不起作用,因为在这两种情况下,您没有在同一对象上同步。当应用于实例方法时,synchronized
关键字会使该方法在上同步。因此,在每种情况下,您都在thread1
的实例上进行同步,其中有两个实例
更有趣的测试是在两个线程中同时运行相同的thread1
实例。在这种情况下,调用wait(1000)
是一件非常糟糕的事情,因为(如文档所述)它会释放此
上的锁。您希望在代码中使用Thread.sleep(1000)
如果需要两个thread1
实例,则需要在某个共享对象上进行同步,可能如下所示:
private static final Object lockObject = new Object();
public void setName(String newName) {
synchronized(lockObject) {
doSetName(newName);
}
}
synchronized
在这里不起作用,因为在这两种情况下,您没有在同一对象上同步。当应用于实例方法时,synchronized
关键字会使该方法在上同步。因此,在每种情况下,您都在thread1
的实例上进行同步,其中有两个实例
更有趣的测试是在两个线程中同时运行相同的thread1
实例。在这种情况下,调用wait(1000)
是一件非常糟糕的事情,因为(如文档所述)它会释放此
上的锁。您希望在代码中使用Thread.sleep(1000)
如果需要两个thread1 public static void main(String[] args) {
Data data = new Data();
Thread task1 = new Thread(new UpdateTask(data));
task1.start();
Thread task2 = new Thread(new UpdateTask(data));
task2.start();
}
}
class UpdateTask implements Runnable {
private Data data;
public UpdateTask(Data data) {
this.data = data;
}
public void run() {
try {
data.updateData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Data {
public synchronized void updateData() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(5000);
System.out.println(i);
}
}
}