Q:

Problema na execução das Threads , usando flags

Estou com uns problemas no entendimento completo do código pois sou novo na utilização do java em thread. O que código vai fazer é controlar o fluxo, fazendo 55 iterações dividindo entre a thread e programa principal (main):
Resultado:
Main Thread.: 1
New Thread..: 2
Main Thread.: 3
New Thread..: 4
...
Main Thread.: 51
New Thread..: 52
Main Thread.: 53
New Thread..: 54

Até aí tudo bem , o problema está , quando em certa execução o programa entra em alguns loop infinito e não para de executar outra vezes ele completa a execução , queria ajuda para entender este problema.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 /
package testando;

/*
 *
 * @author Márcio
 */
public class Testando {
static int value = 0;
static int flag = 1;

@SuppressWarnings("empty-statement")
    public static void main(String[] args) {

                class MyThread extends Thread {

                        @Override
                        public void run() {
                                while(flag == 1);
                                while(++value < 55) {
                                        System.out.println("New Thread..: " + value);
                                        flag = 1;
                                        while( value < 55 && flag == 1);
                                }
                        }
                }

                Thread thread1 = new MyThread();
                thread1.start();
                System.out.println(flag == 0);
                while(flag == 0);
                while(++value < 55) {
                        System.out.println("Main Thread.: " + value);
                        flag = 0;
                        while( value < 55 && flag == 0);
                }
        }
    }

A:

O que está causando racing conditions no seu código é o fato do acesso às variáveis não ser atômica, isto é, elas são acessadas concorrentemente por mais de um thread. Se você quer que essas variáveis sejam usadas pelo código sem que a operação executada em um thread afete a operação executada pelo outro, você deve encapsular as operações de leitura e alteração do valor das variáveis em blocos synchronized (dentro dos quais somente pode entrar um thread de cada vez) ou então usar objetos que garantam a atomicidade da operação como por exemplo AtomicInteger.

