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同步和线程 import java.util.Random; 甲级公共课{ int a=0,b=10; Random rand=新的Random(); 公共同步的void add(){ 如果(a >代码> b>代码>中表示两个数,在其他上下文中,变量 a < /> >和 b>代码>引用类A和类B 的实例。将A类字段转换为其他字段,如number1和number2 “假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法public void f(){val++;synchronized(this){anotherVal++;}}。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量val仍然可以由另一个线程修改,对吗?) import java.util.Random; public class ClassA{ int a = 0, b = 10; Random rand = new Random(); public synchronized void add(){ if (a < 10){ a++; b--; }; } public synchronized void subtract(){ if (b < 10){ b++; a--; } } public synchronized boolean check(){ return a + b == 10; } public static void main(String args[]){ ClassA a = new ClassA(); B ba = new B(a); B bb = new B(a); //notice these two threads are not associated with the object a! Thread t11 = new Thread(bb); Thread t22 = new Thread(ba); t11.start(); t22.start(); } } class B implements Runnable{ ClassA a; B(ClassA a){ this.a = a; } @Override public void run(){ while (a.check()){ if (a.rand.nextInt(2) == 1) a.subtract(); else a.add(); } System.out.print("Out of sync"); } }_Java_Multithreading - Fatal编程技术网

Java同步和线程 import java.util.Random; 甲级公共课{ int a=0,b=10; Random rand=新的Random(); 公共同步的void add(){ 如果(a >代码> b>代码>中表示两个数,在其他上下文中,变量 a < /> >和 b>代码>引用类A和类B 的实例。将A类字段转换为其他字段,如number1和number2 “假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法public void f(){val++;synchronized(this){anotherVal++;}}。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量val仍然可以由另一个线程修改,对吗?) import java.util.Random; public class ClassA{ int a = 0, b = 10; Random rand = new Random(); public synchronized void add(){ if (a < 10){ a++; b--; }; } public synchronized void subtract(){ if (b < 10){ b++; a--; } } public synchronized boolean check(){ return a + b == 10; } public static void main(String args[]){ ClassA a = new ClassA(); B ba = new B(a); B bb = new B(a); //notice these two threads are not associated with the object a! Thread t11 = new Thread(bb); Thread t22 = new Thread(ba); t11.start(); t22.start(); } } class B implements Runnable{ ClassA a; B(ClassA a){ this.a = a; } @Override public void run(){ while (a.check()){ if (a.rand.nextInt(2) == 1) a.subtract(); else a.add(); } System.out.print("Out of sync"); } }

Java同步和线程 import java.util.Random; 甲级公共课{ int a=0,b=10; Random rand=新的Random(); 公共同步的void add(){ 如果(a >代码> b>代码>中表示两个数,在其他上下文中,变量 a < /> >和 b>代码>引用类A和类B 的实例。将A类字段转换为其他字段,如number1和number2 “假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法public void f(){val++;synchronized(this){anotherVal++;}}。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量val仍然可以由另一个线程修改,对吗?) import java.util.Random; public class ClassA{ int a = 0, b = 10; Random rand = new Random(); public synchronized void add(){ if (a < 10){ a++; b--; }; } public synchronized void subtract(){ if (b < 10){ b++; a--; } } public synchronized boolean check(){ return a + b == 10; } public static void main(String args[]){ ClassA a = new ClassA(); B ba = new B(a); B bb = new B(a); //notice these two threads are not associated with the object a! Thread t11 = new Thread(bb); Thread t22 = new Thread(ba); t11.start(); t22.start(); } } class B implements Runnable{ ClassA a; B(ClassA a){ this.a = a; } @Override public void run(){ while (a.check()){ if (a.rand.nextInt(2) == 1) a.subtract(); else a.add(); } System.out.print("Out of sync"); } },java,multithreading,Java,Multithreading,我试图更好地理解java多线程。因此,我知道俗话说,只有一个线程可以访问一个对象实例,从而调用该实例的方法(例如,在本例中,类classA中的subtract方法) 但是,当您仍然有相同的classA,a实例,但是与不同的类classB关联的两个线程试图调用a的方法时,会发生什么情况呢?我原以为消息不同步永远不会被打印出来,但它打印了。毕竟,仍然只有一个线程对象实例a,这是否意味着同步在本例中不适用?在您的情况下,将永远不会打印出不同步的,因为在您的情况下,多线程的实现是正确的:执行一系列操作的

我试图更好地理解java多线程。因此,我知道俗话说,只有一个线程可以访问一个对象实例,从而调用该实例的方法(例如,在本例中,类
classA
中的
subtract
方法)


但是,当您仍然有相同的
classA
a
实例,但是与不同的类
classB
关联的两个线程试图调用
a
的方法时,会发生什么情况呢?我原以为消息
不同步
永远不会被打印出来,但它打印了。毕竟,仍然只有一个线程对象实例
a
,这是否意味着同步在本例中不适用?

在您的情况下,将永远不会打印出不同步的
,因为在您的情况下,多线程的实现是正确的:执行一系列操作的关键方法因此不是原子的,它们的行为就像原子m通过在方法上使用
synchronized
关键字执行方法


假设一个代码块被声明为
synchronized(x)
。 进入该代码块的第一个线程获得object
x
的锁,并愉快地执行该代码块

任何试图进入同一对象
x
上的块的非第一个线程都会通过将该线程放入
x
的锁池而被“挂起”。只要当前具有锁的线程离开
同步(x)
块,锁池中的随机线程就成为执行该块的下一个线程

在实例方法上使用
synchronized
时,它实际上与使用
synchronized(this)
包装方法的整个内容相同(对于
静态
方法,它将是封闭类的类对象)

因此,在您的例子中,类
A
有一个实例,所有同步都发生在它上面

如果要查看
不同步
消息,请尝试删除
已同步
关键字。过一段时间后,您应该会看到预期的
不同步
消息

旁注:

  • 因为
    不同步
    是一条消息,它可能应该打印在
    System.err
    上,而不是
    System.out
  • 您可以使用
    a.rand.nextBoolean()
    ,而不是
    a.rand.nextTint(2)==1
  • 如果
    class A
    class B
    访问字段
    rand
    破坏了封装,您可能希望为
    class A
    提供一个方法
    randomBoolean()
    ,该方法返回rand.nextBoolean()
,并从
class B
调用该方法
randomBoolean()
<> LI>在不同的上下文中具有不同含义的相同变量名可能混淆。在变量<代码> > <代码> >代码> b>代码>中表示两个数,在其他上下文中,变量<代码> a < /> >和<代码> b>代码>引用<代码>类A<代码>和<代码>类B 的实例。将
A类
字段转换为其他字段,如
number1
number2

“假设一个代码块被声明为已同步(x)。进入该代码块的第一个线程获得对象的锁…”对不起,但是代码块之外的代码呢?假设您有一个方法
public void f(){val++;synchronized(this){anotherVal++;}}
。在这种情况下,如何说“首先进入块的线程获得对象x的锁”?(变量
val
仍然可以由另一个线程修改,对吗?)
import java.util.Random;

public class ClassA{
  int a = 0, b = 10;
  Random rand = new Random();

  public synchronized void add(){
      if (a < 10){ 
         a++;
         b--;
      };
  }

  public synchronized void subtract(){
      if (b < 10){ 
         b++;
         a--;
      }
  }
  
  public synchronized boolean check(){
     return a + b == 10;
  }
  
  
  public static void main(String args[]){
      
      ClassA a = new ClassA();
      
      B ba = new B(a);
      B bb = new B(a);
      
       //notice these two threads are not associated with the object a!
      Thread t11 = new Thread(bb);
      Thread t22 = new Thread(ba);
      t11.start(); 
      t22.start();
  }
}


class B implements Runnable{
    ClassA a;
    
    B(ClassA a){
        this.a = a;
    }
   
    @Override
    public void run(){
        while (a.check()){
          if (a.rand.nextInt(2) == 1)
              a.subtract();
          else
              a.add();
      } System.out.print("Out of sync");
    }
}