Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.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_Arraylist - Fatal编程技术网

Java 如果某个类被另一个类更改,如何使更改对一个类可见?

Java 如果某个类被另一个类更改,如何使更改对一个类可见?,java,multithreading,arraylist,Java,Multithreading,Arraylist,我试图将JButton实现为一个线程,由于无法从线程返回JButton,我创建了一个新类AllButtons,在该类中,我将所有JButton存储在一个arrayList中 问题是,当我尝试在Build类中访问我的arrayList时,代码会给我一个异常,即java.lang.IndexOutOfBoundsException。但是,当我在ButtonThread类本身中访问相同的内容时,它会工作 那么,考虑到我已经将对象传递给ButtonThread构造函数,如何在我的Build类中可见myL

我试图将JButton实现为一个线程,由于无法从线程返回JButton,我创建了一个新类
AllButtons
,在该类中,我将所有JButton存储在一个arrayList中

问题是,当我尝试在
Build
类中访问我的arrayList时,代码会给我一个异常,即
java.lang.IndexOutOfBoundsException
。但是,当我在
ButtonThread
类本身中访问相同的内容时,它会工作

那么,考虑到我已经将对象传递给ButtonThread构造函数,如何在我的
Build
类中可见
myList
中的更改呢

类AllButtons,其中包含JButton的arrayList

class AllButtons
{
   //new List
   List<JButton> myList = new ArrayList<JButton>();

   //add to List
   public void addMember(JButton button)
   {
     myList.add(button);
   } 

  //retrieve a particular value from List
   public JButton getButton(int index)
   {
     return myList.get(index);
   }

   //demo display
   public void display()
   {
     System.out.println(myList.get(0));
   }
}
班级建设

class Build
{
   //some code

   AllButtons ab = new AllButtons();

   Build()
   {

      /**
          JFrame code         **/

      //button

      new ButtonThread(ab, 1);  //make new button, object passed as well
      ab.display();  //here it fails,gives exception, list contains nothing, WHY ?

      JButton button1 = ab.getButton(0); //obviously this fails too


      /***********************/
      //JFrame Code//

   }
 }

swing组件的处理应该由事件分派线程完成。从另一个线程执行某些操作,您将使用或

我猜您有一个竞态条件。欢迎使用多线程

请记住,一旦启动第二个线程,您就不知道该线程中的操作将在何时发生,与主线程相关,除非您同步它们

所以可能发生的事情(国际海事组织)是

  • 构造函数调用t.start()(因此“t”线程开始启动)
  • …同时,您的代码在主线程上继续,因此

  • 退出构造函数,返回到构建方法中
  • 运行ab.display()(并引发异常,因为ab为空)
  • 尝试访问ab[0](并由于为空而引发异常)
  • …发生这种情况后,t线程终于启动了,因此

  • 运行并将自身添加到ab
  • 成功运行ab.display()

  • 正如上面提到的Gyro Gearless,您确实需要阅读java中的同步和多线程技术。这是一个非常简单的出错例子,但当事情变得复杂时,除非你真正掌握了如何保持线程安全,否则你将完全迷失方向

    1)在开始多线程编程之前,您应该了解
    volatile
    synchronized
    2)“Swing的线程策略在一般Swing中不是线程安全的。除非另有说明,否则必须在事件调度线程上访问所有Swing组件和相关类。”-此免责声明的存在有一个原因:-)@Gyrogorless可爱可爱:D谢谢!顺便说一句,我不能将评论标记为答案,那么我应该在这里做什么pEven如果我使用
    Swingutilities.invokeLarer
    ,它不会因为Gyro和Theodore提到的比赛条件而有什么不同
    class Build
    {
       //some code
    
       AllButtons ab = new AllButtons();
    
       Build()
       {
    
          /**
              JFrame code         **/
    
          //button
    
          new ButtonThread(ab, 1);  //make new button, object passed as well
          ab.display();  //here it fails,gives exception, list contains nothing, WHY ?
    
          JButton button1 = ab.getButton(0); //obviously this fails too
    
    
          /***********************/
          //JFrame Code//
    
       }
     }