关于相同/不同对象上java线程的混淆

关于相同/不同对象上java线程的混淆,java,multithreading,Java,Multithreading,这里是第二个示例,就像第一个示例一样,我们在类的两个不同实例上创建了一个线程。这里我们同步move()方法,但根据定义: “两个不同的对象可以同时进入同步方法” 请分享您的反馈?您需要了解同步是如何工作的。 线程进入同步块时,会对正在同步的对象进行“锁定”。如果您有一个同步方法,那么在这种情况下,对象将成为“this”实例。现在,没有两个线程可以同时锁定同一个对象。对象锁是基于互斥锁的,所以一次只有一个线程可以持有互斥锁。当持有锁的线程退出同步方法或块时,它会释放互斥锁,因此对象锁可供其他线程请

这里是第二个示例,就像第一个示例一样,我们在类的两个不同实例上创建了一个线程。这里我们同步move()方法,但根据定义: “两个不同的对象可以同时进入同步方法”


请分享您的反馈?

您需要了解同步是如何工作的。 线程进入同步块时,会对正在同步的对象进行“锁定”。如果您有一个同步方法,那么在这种情况下,对象将成为“this”实例。现在,没有两个线程可以同时锁定同一个对象。对象锁是基于互斥锁的,所以一次只有一个线程可以持有互斥锁。当持有锁的线程退出同步方法或块时,它会释放互斥锁,因此对象锁可供其他线程请求锁定


林克很好地解释了这些概念。它有关于反汇编字节码的图片,显示了线程如何获取和离开锁,以及为什么两个不同对象上的两个线程不会相互阻塞。

由于您为每个线程创建了一个新实例,因此您的线程在不同的对象上运行。synchronized使用的内部锁属于该实例。因此,线程输入的同步方法由不同的锁保护。

如果我理解正确,您的问题是:“为什么
移动
方法是同步的?”

答案是:不应该这样,原因有二:

  • 它不访问任何字段,因此在该方法中同时有多个线程不会损坏任何内容

  • 每个线程获得对象的不同实例,从而获得不同的锁。因此,同步修改器没有任何区别。每个线程仍然可以输入自己实例的
    move
    方法,因为它们有单独的锁


  • 只有在线程之间共享某些数据,并且至少有一个线程正在修改该数据时,才需要进行同步。

    在“DiffObjSynchronized”类中,如果move()方法中使用了任何实例变量,那么再次说明为什么需要同步move()因为有两个不同的对象,它们都可以更改任何实例变量。如果我的理解有误,请纠正我?@Adelasghar你是对的。如果每个对象仅由一个线程使用,则无需对其进行同步。
    public class Computation extends Thread {
    
        private int num;
        private boolean isComplete;
    
        public Computation(int nu) {
            num = nu;
        }
    
        public void run() {
            System.out.println("Thread Called is: " + Thread.currentThread().getName());
        }
    
        public static void main(String... args) {
            Computation [] c = new Computation[4];
            for (int i = 0; i < 3; i++) {
                c[i] = new Computation(i);
                c[i].start();
            }
        }
    }
    
    public class DiffObjSynchronized implements Runnable {
    
        @Override
        public void run() {
            move(Thread.currentThread().getId());           
        }
    
        public synchronized void move(long id) {
            System.out.print(id + " ");
            System.out.print(id + " ");
        }
    
        public static void main(String []args) {
            DiffObjSynchronized a = new DiffObjSynchronized();
            /**** output ****/
            // 8    9   8   9
            new Thread(a).start();
            new Thread(new DiffObjSynchronized()).start();
        }
    }