首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java涂料“结巴”-list并发性

Java涂料“结巴”-list并发性
EN

Stack Overflow用户
提问于 2014-10-03 16:53:30
回答 1查看 183关注 0票数 0

我的一个应用程序通过读取数组列表将对象绘制到屏幕上:

简单代码摘要:

代码语言:javascript
复制
@Override
public synchronized void paintComponent(Graphics g) {
  for(Object gO:paintList) {
    g.drawImage( gO.getObjImage(), gO.getXLoc(), gO.getYLoc(), outer.getTransparent(), null);
  }
}

问题是,每次用户单击鼠标时,我都会添加更多的对象,因此如果用户单击的速度足够快,我就会导致程序绘图口吃,因为它在写入时无法读取( arrayList是同步的)。开发人员用来处理这个并发问题的通用实践是什么?

编辑:下面是调用重绘的代码:

代码语言:javascript
复制
byte ticks = 0;
    while(true) {
        currentTime = System.nanoTime();
        if(ticks == 25) {
            drawPanel.repaint();
            ticks = 0;
        } else if (ticks%5 == 0) {//if ticks is a multiple of 5 (5,10,15,...)
            drawPanel.operations();
            ticks++;
        } else if(ticks < 25) {
            ticks++;
        }
        try {
            /*
            Refer to: 'http://stackoverflow.com/questions/1036754/difference-between-wait-and-sleep'
            on differences between Thread.sleep() and wait()
            */
            wait(1);//old timings: (long)(refreshRate*1000)
        } catch (InterruptedException ex) {
            Logger.getLogger(DeathWish.class.getName()).log(Level.SEVERE, null, ex);
        }
        //Debugging
        //System.out.println(ticks);
        currentTime = System.nanoTime();

*如果运算()计算了‘油漆’对象的属性的变化,删除满足某些条件的对象,并将新的对象添加到画图列表中。从逻辑上讲,添加和书写应该分开吗?如果没有足够的信息,我可以发布操作()方法,但是我试图不发布大量的代码,这样就更容易解释了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-03 17:06:35

我想你把同步搞错了:

  • ArrayList是一个没有同步实现的列表。
  • 同步方法意味着一次只有一个线程可以访问该方法,但是函数中的变量根本不同步。

你想要的是让你的列表临时同步。

你可以这样做:

代码语言:javascript
复制
@Override
public void paintComponent(Graphics g) {
  synchronized(paintList) {
    for(Object gO:paintList) {
      g.drawImage( gO.getObjImage(), gO.getXLoc(), gO.getYLoc(), outer.getTransparent(), null);
    }
  }
}

在添加对象的代码中,你的列表也会做同样的事情。

从这里编辑:

如果您想要删除add线程和画板线程之间的所有并发问题,下面是您可以这样做的方法:

在添加图像的方法中:

代码语言:javascript
复制
public synchronized void addImage(...) {
  Something newImage = .....
  List<Something> newPaintList = new ArrayList<>(paintList.size() + 1);
  newPaintList.addAll(paintList);
  newPaintList.add(newImage);
  paintList = newPaintList;
}

在绘制方法中,删除同步部分。

代码语言:javascript
复制
@Override
public void paintComponent(Graphics g) {
  for(Object gO:paintList) {
    g.drawImage( gO.getObjImage(), gO.getXLoc(), gO.getYLoc(), outer.getTransparent(), null);
  }
}

这样,您就不会在读和写之间有任何并发性,因为在paintList上所做的唯一操作就是读。

应该同步addImage以避免同时添加两个不同的线程,这可能会使一个addImage被忽略。

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

https://stackoverflow.com/questions/26183287

复制
相关文章

相似问题

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