首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理素描中的并发修改异常

处理素描中的并发修改异常
EN

Stack Overflow用户
提问于 2017-06-05 15:09:01
回答 1查看 398关注 0票数 0

我正在修改来自毒物库毒物库示例,使其由Leap运动传感器的手势控制,而不是示例中的鼠标。

我在Open应用程序中做所有手势识别,并通过OSC发送。

当发生Gesture 0事件时,我调用下面的方法从physics对象中删除gestureAttractor

代码语言:javascript
复制
void resetAttraction() {
  if (gestureAttractor != null){
      physics.removeBehavior(gestureAttractor);
      println("ATTRACTOR NULL");
     } else {
        println("not null");
     }
}

如果发生Gesture 1事件,则调用此方法来创建新的gestureAttractor,并将其添加回physics对象:

代码语言:javascript
复制
void addAttraction(){ 
   if (gestureAttractor == null) { 
       println("ATTRACTOR NULL"); 
       position1.set(340, 191); 
       gestureAttractor = new AttractionBehavior2D(position1, 250, 0.9f); 
       physics.addBehavior(gestureAttractor); 
   } else { 
       println("not null"); 
   } 
}

似乎一贯发生的情况是,每当手势状态发生变化时,我将在ConcurrentModificationException方法中的physics.update();中得到一个draw崩溃。

我确信这与处理这些对象的生命周期有关,但我还无法确定任何东西--有人有任何想法吗?

以下是草图的全部内容:

代码语言:javascript
复制
import toxi.geom.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;

import oscP5.*;
import netP5.*;

OscP5 oscP5;

int NUM_PARTICLES = 750;

VerletPhysics2D physics;
//AttractionBehavior2D mouseAttractor;
AttractionBehavior2D gestureAttractor;


//Vec2D mousePos;
Vec2D position1;


boolean isGestureAttractorAdded;

void setup() {
  size(680, 382,P3D);
  // setup physics with 10% drag
  physics = new VerletPhysics2D();
  physics.setDrag(0.05f);
  physics.setWorldBounds(new Rect(0, 0, width, height));
  // the NEW way to add gravity to the simulation, using behaviors
  physics.addBehavior(new GravityBehavior2D(new Vec2D(0, 0.15f)));

  // start oscP5, listening for incoming messages at port 12000 
  oscP5 = new OscP5(this, 6000);

  position1 = new Vec2D(340, 191);

  addAttraction();

  //gestureAttractor = new AttractionBehavior2D(position1, 250, 0.9f);
  //physics.addBehavior(gestureAttractor);
}

void addParticle() {
  VerletParticle2D p = new VerletParticle2D(Vec2D.randomVector().scale(5).addSelf(width / 2, 0));
  physics.addParticle(p);
  // add a negative attraction force field around the new particle
  physics.addBehavior(new AttractionBehavior2D(p, 20, -1.2f, 0.01f));
}

void draw() {
  background(255,0,0);
  noStroke();
  fill(255);
  if (physics.particles.size() < NUM_PARTICLES) {
    addParticle();
  }
  physics.update();
  for (VerletParticle2D p : physics.particles) {
    ellipse(p.x, p.y, 5, 5);
  }
}

void mousePressed() {
  //position1 = new Vec2D(mouseX, mouseY);
   //create a new positive attraction force field around the mouse position (radius=250px)
  //gestureAttractor = new AttractionBehavior2D(position1, 250, 0.9f);
  //physics.addBehavior(gestureAttractor);

  //println(physics.behaviors);
}

void mouseDragged() {
  // update mouse attraction focal point
  //position1.set(mouseX, mouseY);
}

void mouseReleased() {
  // remove the mouse attraction when button has been released
  //physics.removeBehavior(gestureAttractor);
}


///// OSC RECEIVING

void oscEvent(OscMessage theOscMessage) {
  /* check if theOscMessage has the address pattern we are looking for. */

  if (theOscMessage.checkAddrPattern("/gesture_classification") == true)  {
    /* check if the typetag is the right one. */
    if(theOscMessage.checkTypetag("i")) {
      /* parse theOscMessage and extract the values from the osc message arguments. */
      int gestureClassLabel = theOscMessage.get(0).intValue();  
      println(" Gesture is: ", gestureClassLabel);

      if (gestureClassLabel == 0){   
        resetAttraction();
      } else if (gestureClassLabel == 1) {       
        addAttraction();
      } else if (gestureClassLabel == 2) {
          //physics.removeBehavior(gestureAttractor);
      } 
    }  
  } 

}

//////METHODS FOR SETTING POSITION / REMOVAL OF ATTRACTORS...

void resetAttraction() {
  if (gestureAttractor != null){
      physics.removeBehavior(gestureAttractor);
      println("ATTRACTOR NULL");
     } else {
        println("not null");
     }
 }

void addAttraction(){
     if (gestureAttractor == null) {
         println("ATTRACTOR NULL");
         position1.set(340, 191);
         gestureAttractor = new AttractionBehavior2D(position1, 250, 0.9f);
         physics.addBehavior(gestureAttractor);
     } else {
       println("not null");
     }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-05 17:30:45

tl;dr:,在从另一个线程迭代数据结构时,不应该用一个线程来修改它。

draw()函数发生在一个线程上,它正在访问和修改物理库中的数据结构。

oscEvent()函数发生在另一个线程上,它还访问和修改这些相同的数据结构。这就是导致你错误的原因。请注意,将其封装在try块中是而不是修复任何东西。当错误发生时,它只是打印出更多的信息。

要真正解决这个问题,您需要读取线程之间的同步数据访问。例如,可以使用同步块来防止不同的线程访问相同的数据结构。如果你谷歌你的错误,你会发现大量的结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44372003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档