Java线程中的synchronized关键字

Java线程中的synchronized关键字,java,multithreading,synchronization,Java,Multithreading,Synchronization,我试图了解多线程(特别是使用synchronized关键字)是如何工作的。所以我在run函数中使用了synchronized关键字。但是输出行显示: 此线程中的初始余额为10000 这个线程的初始余额是10000 这是我关心的。因为初始余额应该是“-243000”,如输出行所示 初始-243000后的最终余额为59049000 由于synchronized关键字,abc1线程应该等待abc。 首先,我希望线程的行为就像我写的一样 abc.start abc.join() abc1.start()

我试图了解多线程(特别是使用synchronized关键字)是如何工作的。所以我在run函数中使用了synchronized关键字。但是输出行显示:

此线程中的初始余额为10000
这个线程的初始余额是10000

这是我关心的。因为初始余额应该是“-243000”,如输出行所示

初始-243000后的最终余额为59049000

由于synchronized关键字,abc1线程应该等待abc。 首先,我希望线程的行为就像我写的一样

abc.start
abc.join()
abc1.start()
abc1.join()
以下是我的源代码:

class parallel extends Thread{
    account a;
    public parallel(account a) {
        this.a=a;
    }
    public synchronized void run() {
        
        synchronized(this) {
            System.out.println("Initial balance in this thread is "+a.amount);
            long duplicate=a.amount;
            boolean flag=true;
            //System.out.println("Transaction inititated");
            for(int i=0;i<10;i++) {
                if(flag==true) {
                    //System.out.println("Deducting "+amount+"Rs from your account");
                    a.amount-=a.amount*2;
                }
                else {
                    //System.out.println("Depositing "+amount+"Rs from your account");
                    a.amount+=a.amount*2;
                }
                flag=!flag;
            }
            System.out.println("Final balance after intial "+duplicate+" is "+a.amount);
            syncro.amount=a.amount;
        }
        
    }   
    
}
class account{
    public account(long rupe) {
        amount=rupe;
    }
    long amount;
}
public class syncro {
    static long amount;
    public static void main(String[] args) throws InterruptedException{
        
        
        //for(int i=0;i<10;i++) {
            account ramesh=new account(1000);
            parallel abc=new parallel(ramesh);
            parallel abc1=new parallel(ramesh);
            
            abc.start();
            //abc.join();
            abc1.start();
            //abc1.join();
            
        //}
        //awaitTermination();
        //Thread.sleep(4000);
            boolean ab=true;
            long cd=1000;
            for(int i=0;i<10;i++) {
                if(ab==true) {
                    //System.out.println("Deducting "+ab+"Rs from your account");
                    cd-=cd*2;
                }
                else {
                    //System.out.println("Depositing "+a+"Rs from your account");
                    cd+=cd*2;
                }
                ab=!ab;
            }
        //System.out.println("Final amount by multithreading is "+);
        
        System.out.println("Final amount after serial order is "+cd);


    }

}
类并行扩展线程{ 账户a; 公共平行账户(账户a){ 这个a=a; } 公共同步的无效运行(){ 已同步(此){ System.out.println(“此线程中的初始余额为“+a.amount”); 长复制=a.金额; 布尔标志=真; //System.out.println(“事务初始化”);
对于(inti=0;i,您将创建自己的线程与使用synchronized混合在一起。此外,在synchronized方法中使用synchronized(this)也会两次执行相同的操作


Synchronized不是关于启动线程。它是关于一次只允许一个线程输入特定的代码块。

您将创建自己的线程与使用Synchronized混合在一起。此外,在Synchronized方法中使用Synchronized(this)是两次执行相同的操作


Synchronized不是关于启动线程。它是关于一次只允许一个线程输入特定的代码块。

您创建的每个对象都有一个隐藏字段,您无法读取,但它确实存在。它属于thread类型,称为
所有者

synchronized
关键字与此隐藏字段交互

synchronized (object) {
   code();
}
指以下各项:

  • 如果
    object.owner==Thread.currentThread()
    ,则继续并递增一个计数器
  • 如果
    object.owner==null
    ,则运行
    object.owner=Thread.currentThread()
    ,将计数器设置为1,然后继续运行
  • 否则(因此,object.owner是另一个线程),停止,冻结线程,然后等待,直到owner设置为null,然后我们可以转到选项#2
  • 进入后,运行code()。当到达右大括号时,减小计数器。如果计数器为0,则运行
    object.owner=null
  • 此外,上述所有操作都是以原子方式进行的,两个线程不可能进入竞态状态来完成所有这些操作。例如,如果两个线程正在等待所有者再次取消设置,则只有一个线程将“获取”,而另一个线程将继续等待。(哪一个得到了它?VM impl可以自由选择它想要的任何东西;您应该假设它是任意的但不公平的。换句话说,不要编写依赖于特定选择的代码)
  • 关键字为
    synchronized
    的方法只是语法糖,用于将其中的所有代码包装在
    synchronized(this)
    中(例如方法)和
    synchronized(MyClass.this)
    中(静态方法)
  • 请注意,
    synchronized
    因此仅与其他
    synchronized
    块交互,并且仅与括号中的对象为完全相同的obj引用的块交互,否则这一切都不起任何作用。它当然不会启动线程!同步所做的一切都可能是暂停线程


    在您的代码中,您已经将所有运行代码放在一个巨大的同步块中,在线程实例上同步。一般来说,当您在任何东西上同步时,它是公共API-其他代码可以在同一事物上同步并影响您。就像我们通常不在java中编写公共字段一样,您应该不要锁定公共字段事物
    通常是公共的(例如,您不控制的代码可以保存对您的引用)。因此,除非您愿意在文档中说明如何设置锁定行为,否则不要这样做。相反,创建一个内部private final字段,将其称为lock,并使用该字段(
    private final Object lock=new Object()

    您创建的每个对象都有一个隐藏字段,您无法读取,但它确实存在。它属于Thread类型,称为
    所有者

    synchronized
    关键字与此隐藏字段交互

    synchronized (object) {
       code();
    }
    
    指以下各项:

  • 如果
    object.owner==Thread.currentThread()
    ,则继续并递增一个计数器
  • 如果
    object.owner==null
    ,则运行
    object.owner=Thread.currentThread()
    ,将计数器设置为1,然后继续运行
  • 否则(因此,object.owner是另一个线程),停止,冻结线程,然后等待,直到owner设置为null,然后我们可以转到选项#2
  • 进入后,运行code()。当到达右大括号时,减小计数器。如果计数器为0,则运行
    object.owner=null
  • 此外,上述所有操作都是以原子方式进行的,两个线程不可能进入竞态状态来完成所有这些操作。例如,如果两个线程正在等待所有者再次取消设置,则只有一个线程将“获取”,而另一个线程将继续等待。(哪一个得到了它?VM impl可以自由选择它想要的任何东西;您应该假设它是任意的但不公平的。换句话说,不要编写依赖于特定选择的代码)
  • 关键字为
    synchronized
    的方法只是语法糖,用于将其中的所有代码包装在
    synchronized(this)
    中(例如方法)和
    synchronized(MyClass.this)
    中(静态方法)
  • 请注意,
    synchronized
    因此只与其他
    synchronized进行交互