Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我们什么时候需要实际同步?我的线程是自然同步的_Java_Multithreading - Fatal编程技术网

Java 我们什么时候需要实际同步?我的线程是自然同步的

Java 我们什么时候需要实际同步?我的线程是自然同步的,java,multithreading,Java,Multithreading,这是我的示例类:我有一个共享对象CustomerAccount在两个线程Man和Woman之间共享。无论何时运行程序,结果都是一致的。为什么会这样 主要类别: package testjava; public class PlaywithThreads { public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub

这是我的示例类:我有一个共享对象
CustomerAccount
在两个线程
Man
Woman
之间共享。无论何时运行程序,结果都是一致的。为什么会这样

主要类别:

package testjava;

public class PlaywithThreads {

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        CustomerAccount ca=new CustomerAccount(0);
        ThreadRunner1 tr1=new ThreadRunner1(ca,"Man");
        ThreadRunner1 tr2=new ThreadRunner1(ca,"Woman");

        tr1.start();
        tr2.start();
        tr1.join();
        tr2.join();
        System.out.println("Final amount left after month"+ca.acctBalance);
    }
}   
螺纹等级:

package testjava;

public class ThreadRunner1 extends Thread{
    private CustomerAccount ca;

    ThreadRunner1 (CustomerAccount ca,String name)
       {

          super (name); 

          this.ca = ca; 
          System.out.println("after this it will create new object");
       }

@Override
public void run() {
    Thread current = Thread.currentThread();
    String name = current.getName();
    System.out.println("Name is"+name);

    // TODO Auto-generated method stub
    if (name.equals("Man")){
        //CustomerAccount caMan = new CustomerAccount();
        /*ca.creditSalary(80000);
        System.out.println(name+""+ca.acctBalance);
        ca.debitFood(8000);

        ca.debitLoans(40000);
        System.out.println(name+""+ca.acctBalance);
        ca.creditBonus(3);

        ca.debitTransport(2000);*/
        ca.acctBalance=ca.acctBalance+80000;
        ca.acctBalance=ca.acctBalance-8000;
        ca.acctBalance=ca.acctBalance-40000;
        ca.acctBalance=ca.acctBalance+3;
        ca.acctBalance=ca.acctBalance-2000;
        System.out.println(name+"----------finally------------"+ca.acctBalance);
    }

    if (name.equals("Woman")){

        //CustomerAccount caWoMan = new CustomerAccount();
        /*ca.creditSalary(50000);
        System.out.println(name+""+ca.acctBalance);
        ca.creditBonus(4);

        ca.debitClothes(20000);


        ca.debitLoans(9000);*/
        ca.acctBalance=ca.acctBalance+50000;
        ca.acctBalance=ca.acctBalance+4;
        ca.acctBalance=ca.acctBalance-20000;
        ca.acctBalance=ca.acctBalance-9000;
        System.out.println(name+"---------Finally-------"+ca.acctBalance);
    }

}
}
共享对象:

package testjava;

public class CustomerAccount {

    int acctBalance;


   // private static int counter;

    public CustomerAccount(int initialBalance) {
        System.out.println("entered");

        this.acctBalance=initialBalance;
        //System.out.println("objects created******************"+counter);
    }
    public void debitFood(int amt){
        System.out.println("debiting food items::for"+Thread.currentThread().getName());
        acctBalance = acctBalance-amt;
        System.out.println("New acct Balance after food debits::"+acctBalance);
    }
    public void debitClothes(int amt){
        System.out.println("debiting clothescost::"+Thread.currentThread().getName());
        acctBalance = acctBalance-amt;
        System.out.println("New acct Balance after clotehs debits::"+acctBalance);
    }
    public void debitTransport(int amt){
        System.out.println("debiting transport::"+Thread.currentThread().getName());
        acctBalance = acctBalance-amt;
        System.out.println("New acct Balance after transport debit::"+acctBalance);
    }
    public void debitLoans(int amt){
        System.out.println("debiting loans::"+Thread.currentThread().getName());
        acctBalance =acctBalance-amt;
        System.out.println("New acct Balance after Loans debit::"+acctBalance);
    }
    public void creditSalary(int salary){
        System.out.println("crediting salary for ::"+Thread.currentThread().getName());
        acctBalance =acctBalance+salary;
        System.out.println("New acct Balance after salary credit::"+acctBalance);
    }
    public void creditBonus(int salary){
        System.out.println("crediting bonus for ::"+Thread.currentThread().getName());
        acctBalance =acctBalance+salary;
        System.out.println("New acct Balance after salary credit::"+acctBalance);
    }
}

由于
CustomerAccount
对象是共享的,您应该在那里处理同步。直接成员访问无法做到这一点(从封装的角度来看,这是一个坏主意)。我建议您研究一下
AtomicInteger
作为
acctBalance
的更好类型,它是线程安全的现成工具,但您也可以使
CustomerAccount
的所有方法同步


看起来线程是同步的,因为您有很多权限访问synchronizing
System.out.println()
!如果您删除printf调试并创建更高的负载,您将看到不同的行为。

是的,因为它在两个线程都完成工作后正确地给出了结果。51007这与我从公共余额中添加或减去数量时得到的结果相同。您所说的“我的线程自然同步”是什么意思?从我们的代码中我看到它们不是。代码太简单了,如果您想看到同步的效果,请尝试在
run
方法中添加一个随机等待,例如:
Thread.sleep(Math.ceil(Math.random()*1000))
很抱歉,这段代码非常糟糕。我建议将其发布到stackoverflow的CodeReview中,以供改进。bashnesnos-这很伤脑筋。我已经删除了println语句,现在我明白了,无论睡眠时间如何,我的操作都会连续进行,并给出相同的结果。我正在考虑创建一个更复杂的操作,以确保它失败。有什么建议吗?