1

私は複数のボールが跳ねるという学校のプロジェクトに取り組んでいます。これまでのところ、私はアプリを作成することができ、すべてが正常に機能します。しかし、アプリにマルチスレッドを実装する必要もあり、これが行き詰まっています。私は1つのボールと1つのスレッドを考えていましたが、それをどのように実装するかがわかりません。これまでの私のコードは次のとおりです(一部):

public void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            //The balls are painted only after the timer is started
            if(bTimer)
            {
                for(Ball ball:ballList.ballsArrayList) 
                {
                    Thread ballThread = new Thread(ball);
                    ballThread.start();
                    ball.draw(g);

                    /*other code for moving the ball*/
                }
            }
        }

クラスボール:

     public void draw(Graphics g) {
          Color color = new Color(this.getColorR(),this.getColorG(),this.getColorB());
          g.setColor(color);
          int radius = this.getsize();
          g.fillOval((int)(this.getX() - radius), (int)(this.getY() - radius), (int)(2 *     
          radius), (int)(2 * radius));

       }

     public void run() {  

            String name = Thread.currentThread().getName();  

            for (int i = 0; i < 200; i++) {  

                //ball.draw(g); ??

                try {  
                    Thread.sleep(50); 
                    System.out.println("Sleeping");
                } catch (Exception ex) {}  
            }  
        }  

スレッドのrun()関数にball.draw()関数を入れることができると思っていました。しかし、どうすればそれができるのか、それが良い考えかどうかはわかりません。マルチスレッドは、私が理解して実装するのがまだ難しいです=((

4

2 に答える 2

2

本当の答えではありませんが、コメントするには長すぎます。

Swing はスレッドセーフではないことに注意してください。すべての Swing コンポーネントは、イベント ディスパッチ スレッドで、そのスレッドでのみアクセスする必要があります。詳細については、Swingガイドの同時実行を参照してください。

これは、ボールの位置を更新するボールごとに 1 つのスレッドを持つことができることを意味します。ただし、ペイント中にボールの位置にアクセスすると、このアクセスは EDT で発生します。つまり、バックグラウンド スレッドでボールの位置をいつでも更新することはできません。ロックを実装するか、単に EDT の位置を更新する必要があります。

何を達成しようとしているのかはわかりませんが、単に特定の時間間隔でボールの位置を更新したい場合は、javax.swing.Timer. このタイマーは EDT でトリガーされるため、スレッドセーフな方法で位置を更新できます。Swing wiki タグには、Swing でアニメーションを実装するためのリンクがいくつか含まれています。

于 2012-11-02T10:38:35.233 に答える
1

すべてのスイング コードは、イベント ディスパッチ スレッドで実行する必要があります。したがって、コード スニペットで行っていることは悪いことです。

ただし、ボールの位置の計算に CPU が集中し、時間がかかる場合は、ロジックを別のスレッドに移動する必要があります。そうしないと、UI が応答しなくなります。

これは、典型的なプロデューサー/コンシューマーの問題になります。1 つのスレッドが座標を生成し、イベント ディスパッチ スレッドがボールを描画してそれらを消費します。

于 2012-11-02T11:04:47.143 に答える