import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class Threads extends JPanel {
    private final ArrayList<Point> pointsRed = new ArrayList<>();
    private final ArrayList<Point> pointsBlue = new ArrayList<>();
    private final Object lock = new Object();

    public Threads() {
        new Thread(new PointAnimator(pointsRed, Color.RED, 1)).start();
        new Thread(new PointAnimator(pointsBlue, Color.BLUE, 1)).start();


    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        synchronized (lock) {
            g.setColor(Color.RED);
            for (Point point : pointsRed) {
                g.fillOval(point.x, point.y, 3, 15);
            }
            g.setColor(Color.BLUE);
            for (Point point : pointsBlue) {
                g.fillOval(point.x, point.y + 5, 3, 15);
            }
        }
    }

    private class PointAnimator implements Runnable {
        private final ArrayList<Point> points;
        private final Color color;
        private final int pointsPerIteration;

        public PointAnimator(ArrayList<Point> points, Color color, int pointsPerIteration) {
            this.points = points;
            this.color = color;
            this.pointsPerIteration = pointsPerIteration;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (lock) {
                    for (int i = 0; i < pointsPerIteration; i++) {
                        points.add(new Point(0, color == Color.RED ? 10 : 30));
                        repaint();
                        try {
                            Thread.sleep(5);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                }
                updatePoints();
            }
        }

        private void updatePoints() {
            synchronized (lock) {
                for (Point point : points) {
                    point.x += 1;
                }
            }
        }
    }
}
