Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.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_Thread Synchronization - Fatal编程技术网

java中的线程同步

java中的线程同步,java,thread-synchronization,Java,Thread Synchronization,为什么我无法在以下程序中实现同步: class P { synchronized void pp(String s) { System.out.println (s); } } class threadA extends Thread { P ob; String s; threadA (P ob, String s) { this.ob = ob; this.s = s; }

为什么我无法在以下程序中实现同步:

class P
{

synchronized void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
        ob.pp (s);
        try
        {
            Thread.sleep (1000);
        }
        catch (Exception e) {}
        }
    }
}


class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}
作品:

你好,用户

再见用户

你好,用户

再见用户

再见用户

我希望OP的形式为:

你好,用户

你好,用户

你好,用户

再见用户

再见用户

再见,用户


或者我的同步概念是错误的?

您不能从p类执行此类同步。现在发生的情况是,如果另一个线程当前正在执行该方法,那么对pp的任何调用都将被阻止。只要该方法结束(如果您只是要将内容打印到控制台,那么该方法很快),下一个线程就可以进入该方法

您试图实现的目标是不可能的,除非两个线程都知道彼此并相互通信。换句话说,当第一个线程完成它需要做的事情时,它应该显式地通知第二个线程开始。这实际上是按顺序执行,而不是并行执行

使现代化 你想想象发生了什么,所以我在这里做

您创建了2个线程。 你开始第一个线程。 第一个线程开始运行,而一段时间后第二个线程也开始运行。 当第一个线程运行时,它进入for循环。然后它叫P.pp。 当从第一个线程调用P.pp时,它锁定P对象。 由于这个方法很短,它将很快退出。 当该方法退出时,它将释放P上的锁。 如果第二个线程在第一个线程退出之前到达同步块,它将等待阻塞。 当第一个线程退出时,当第一个线程释放锁时,第二个线程进入。 第一个线程返回循环并再次尝试调用P.pp。 这将继续,取决于哪个线程更快,执行顺序将有所不同。
您不能从p类执行此类同步。现在发生的情况是,如果另一个线程当前正在执行该方法,那么对pp的任何调用都将被阻止。只要该方法结束(如果您只是要将内容打印到控制台,那么该方法很快),下一个线程就可以进入该方法

您试图实现的目标是不可能的,除非两个线程都知道彼此并相互通信。换句话说,当第一个线程完成它需要做的事情时,它应该显式地通知第二个线程开始。这实际上是按顺序执行,而不是并行执行

使现代化 你想想象发生了什么,所以我在这里做

您创建了2个线程。 你开始第一个线程。 第一个线程开始运行,而一段时间后第二个线程也开始运行。 当第一个线程运行时,它进入for循环。然后它叫P.pp。 当从第一个线程调用P.pp时,它锁定P对象。 由于这个方法很短,它将很快退出。 当该方法退出时,它将释放P上的锁。 如果第二个线程在第一个线程退出之前到达同步块,它将等待阻塞。 当第一个线程退出时,当第一个线程释放锁时,第二个线程进入。 第一个线程返回循环并再次尝试调用P.pp。 这将继续,取决于哪个线程更快,执行顺序将有所不同。
Synchronized关键字意味着该代码块上的两个线程必须遵守它们试图访问该块代码的顺序。这并不意味着执行流是序列化的


要获得您想要的内容,请尝试将for放入synchronized块中…

synchronized关键字意味着该代码块上的两个线程必须遵守它们尝试访问该块代码的顺序。这并不意味着执行流是序列化的


要获得您想要的内容,请尝试将for放入同步块中…

您应该尝试以下方法

class P
{

void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
            synchronized(ob)
            {
               ob.pp (s);
                try
                {
                    Thread.sleep (10);
                }
                catch (Exception e) {}
            }


        }
    }
}


public class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}

i、 e在睡眠时保持线程同步,这样您就可以获得所需的输出,否则您就不能确定睡眠后哪个线程可能首先出现。请参见

您应该尝试这样的方法

class P
{

void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
            synchronized(ob)
            {
               ob.pp (s);
                try
                {
                    Thread.sleep (10);
                }
                catch (Exception e) {}
            }


        }
    }
}


public class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}
i、 e在睡眠时保持线程同步,这样您就可以获得所需的输出,否则您就不能确定睡眠后哪个线程可能首先出现。看

你能给我解释一下我的程序的控制流程吗

Hello启动并运行循环,直到它到达synchronized方法

再见,我也是

Hello是第一个获得锁的人

再见,等待锁的街区

Hello执行该方法并释放锁

Bye现在可以获得锁,Hello已经释放了它

Bye现在可以执行该方法,并像Hello那样释放锁


我该怎么做才能使hello在执行该方法后进入阻塞池,并且不会将锁留给bye来获取它

握住锁,如果你想保留它,就不要松开它

public void run() {
    synchronized(ob); { // hold the lock the whole time
        for (int i = 1; i <= 5; ++i) {
            ob.pp (s);
            try { Thread.sleep(1000); } catch (Exception e) {}
        }
    } // releases the lock here.
}
你能给我解释一下程序的控制流程吗 是吗

Hello启动并运行循环,直到它到达synchronized方法

再见,我也是

Hello是第一个获得锁的人

再见,等待锁的街区

Hello执行该方法并释放锁

Bye现在可以获得锁,Hello已经释放了它

Bye现在可以执行该方法,并像Hello那样释放锁


我该怎么做才能使hello在执行该方法后进入阻塞池,并且不会将锁留给bye来获取它

握住锁,如果你想保留它,就不要松开它

public void run() {
    synchronized(ob); { // hold the lock the whole time
        for (int i = 1; i <= 5; ++i) {
            ob.pp (s);
            try { Thread.sleep(1000); } catch (Exception e) {}
        }
    } // releases the lock here.
}


只有pp方法中的代码是同步的,所以当您在睡眠中等待时,没有任何东西是同步的。似乎要同步run方法,以便可以使用synchronizedThreadA.class{try{…}但是即使这样也不能保证你在开始之前就需要像CountdownLatch这样的东西:我脑海中的控制流是这样的:请纠正我的错误:线程a有机会用字符串s=Hello User运行它调用pp然后这个线程a进入阻塞池执行控制进入线程b和sa类P的me对象到达那里后,线程b发现方法pp是同步的,线程b没有进入pp的锁,因为它与线程a在阻塞池中,因此现在不打印OP控制返回线程a,循环继续,直到i!=5只有pp方法中的代码是同步的,所以当您如果您正在睡眠中等待,则未同步任何内容。您似乎希望同步run方法,以便可以使用synchronizedThreadA.class{try{…}但是即使这样也不能保证你在开始之前就需要像CountdownLatch这样的东西:我脑海中的控制流是这样的:请纠正我的错误:线程a有机会用字符串s=Hello User运行它调用pp然后这个线程a进入阻塞池执行控制进入线程b和sa类P的me对象到达那里后,线程b发现方法pp是同步的,线程b没有进入pp的锁,因为它与线程a在阻塞池中,因此现在不打印OP。控制返回线程a,循环继续,直到i!=5。我想的是:请更正我在哪里rong:-线程a有机会使用字符串s=Hello User运行它调用pp,然后该线程a进入阻塞池。执行控制进入线程b,在到达该池后,使用类P的相同对象。线程b发现方法pp是同步的,线程b没有进入pp的锁,因为它与处于阻塞池因此不打印OP现在控制返回到线程a,循环继续,直到i!=5请纠正我在这个循环流中的错误control@vrnvav97当第一个线程退出synchronized方法时,它会释放锁,允许另一个线程获取锁与您所做的相同,如果锁定的工作方式与您预期的相同,那么只有一个线程可以打印到屏幕上,这显然是不受欢迎的。@PeterLawrey,您可以向我解释一下我的程序的控制流程吗?@Jai我该怎么做,以便当第一个线程在执行pp后退出pp时,该线程不会将锁留给第二个线程获取它。w我脑子里想的是:请纠正我错的地方:-线程a有机会运行它调用pp并使用字符串s=Hello User然后这个线程a进入阻塞池执行控制进入线程b在到达那里后,线程b发现方法pp是同步的,线程b没有锁进入pp,因为它与线程a在阻塞池中,因此不打印OP。现在控制返回到线程a,循环继续,直到i!=5。请纠正我在该流程中的错误control@vrnvav97当第一个线程退出synchronized方法时,它释放锁,允许另一个线程获取e lock.注意:System.out.println也使用与您相同的锁定方式,如果锁定的工作方式与您期望的相同,那么只有一个线程可以打印到屏幕上,这显然是不受欢迎的。@PeterLawrey,您能解释一下我的程序的控制流吗?@Jai我该怎么做,当第一个线程在执行后退出pp时,线程会这样做esn不会将锁留给第二个线程来获取它。如果同步块在循环之外,它会工作。这仍然会释放锁并允许另一个线程获取它。但是我认为我的程序的控制流是假设线程a有机会运行它,并使用字符串s=Hello User调用pp,那么这个线程就可以运行了当执行控制到达阻塞池后,执行控制转到线程b,线程b发现方法pp是同步的,并且线程b没有锁

进入pp,因为它与线程a在阻塞池中,因此现在不打印OP。控制返回到线程a,循环继续,直到i!=5请纠正我在这个控制流中的错误,考虑这样一种情况,threadA已经执行pp并且处于睡眠状态,threadA已经完成了它的同步状态,pp上没有锁,所以任何其他线程都可以获得锁,在这种情况下,你无法预测执行顺序。如果同步块是在循环之外。这仍然会释放锁并允许另一个线程获取它。但我认为我的程序的控制流是假设线程a有机会运行它,并使用字符串s=Hello User调用pp,然后该线程a进入阻塞池,执行控制进入线程b,之后使用类P的相同对象到达那里线程b发现方法pp是同步的,线程b没有进入pp的锁,因为它与线程a在阻塞池中,因此现在不打印OP控制返回到线程a,循环继续,直到i!=5请纠正我在这个控制流中的错误,考虑一个例子,threadA已经执行了pp并且处于睡眠状态,threadA已经完成了它的同步状态,pp上没有锁,所以任何其他线程都可以获得锁,在这种情况下,你无法预测执行顺序。在执行之后,我能做些什么,hello该方法转到blocked pool,也不会为bye留下获取它的锁,但是如果我想在整个方法中使用synchronized关键字,而不仅仅是block,该怎么办呢。我的方法也应该在P类中。你能解释一下这个程序的流程吗:-类共享{int x;同步的void show String s,int a{x=a;SOPln s++x;尝试{Thread.sleep2000;}catch}//线程程序运行s.show HELLO,10;//其中s是共享类object@vrnvav97你能提供更多的细节吗?你有不止一个线程吗?你有什么疑问吗?我该怎么做才能让hello在执行方法后进入阻塞池,也不会留下锁让bye获取它,但是如果我想使用synchronized关键字wit呢整个方法,而不仅仅是块。我的方法也应该在P类中。你能给我解释一下这个程序的流程吗:-类共享{int x;同步无效显示字符串s,int a{x=a;SOPln s++x;尝试{Thread.sleep2000;}catch}//线程程序运行s.show HELLO,10;//其中s是共享类object@vrnvav97你能提供更多的细节吗?你有多条线索吗?你有什么疑问?