2015-11-01 49 views
0

本周我开始使用Java线程和并发;我需要一些帮助,我已经使用实现下一个代码Thread代替Runnable无法演示并发增量/减量

package hilos; 

public class Hilo extends Thread { 

//Atributos 

public static int concurso = 0; 
private int veces; 
private boolean incrementoDecremento; 

//Método constructor 

public Hilo(boolean inc, int numeroVeces){ 

    this.incrementoDecremento = inc; 
    this.veces = numeroVeces; 
} 

//Método run 

@Override 

public void run(){ 

    for(int i = 0; i < this.veces; i++){  

     if(this.incrementoDecremento == true){ 

      concurso++; 
      System.out.println("La variable introducida es: " + concurso); 

     }else{ 

      concurso--; 
      System.out.println("La variable introducida es: " + concurso); 
     } 
    } 
} 
} 

主要

package hilos; 

public class Usa_Hilos { 

public static void main(String[] args) { 

    int prueba = 5; 
    Hilo positivo = new Hilo(true, prueba); 
    Hilo negativo = new Hilo(false, prueba); 


    positivo.start(); 
    negativo.start(); 

    try{ 

     positivo.join(); 
     negativo.join(); 
    }catch(InterruptedException ex){ 

     System.out.println("Se ha producido un error."); 
    } 
} 

} 

我的目标是,如果我有两个任务使用相同的值,都开始递增和随机递减,所以基本上它会导致一个随机值由va确定ribly prueba它位于Main类。

问题是,出于某种原因,我一直在不断测试,最终结果始终为零。我用​​声明和Runnable实现这个没有问题,但对我来说使用Thread是不可能的。你能帮我吗?

+1

如果您增加一个变量5次并将其减少5次,它将与开始时的值相同(即0)。在你的例子中,你没有看到任何异质情况的不良影响,所以它可以直接匹配。如果你测试更大的计数或可能更大的线程,结果可能不会总结为0,因为你没有使用原子操作。 – eckes

+0

你有很多问题。有些严重,有些非常严重。首先,除非实际上扩展Thread的功能,否则不要'扩展Thread' - 而是使用'Runnable'。在非常严重的问题 - 你有很多访问变量没有内存障碍;这被称为竞态条件 - 你需要阅读同步和volatile参考。 –

回答

2

尝试大于5的数字。您的线程可能运行得非常快,以至于第一个线程在第二个线程启动之前完成。

10000证明这个问题对我罚款:

public class BadThreads { 
    public static void main(String[] args) { 
     MyThread t1 = new MyThread(10000); 
     MyThread t2 = new MyThread(-10000); 
     t1.start(); 
     t2.start(); 
     try { 
      t1.join(); 
      t2.join(); 
     } catch (InterruptedException e) { 
      System.out.println("interrupted"); 
     } 
     System.out.println(MyThread.shared); 
    } 

    private static class MyThread extends Thread { 
     public static int shared; 
     private int change; 

     public MyThread(int change) { 
      this.change = change; 
     } 

     public void run() { 
      while (change < 0) { 
       change++; 
       shared--; 
      } 
      while (change > 0) { 
       change--; 
       shared++; 
      } 
     } 
    } 
} 

结果:

tmp$ javac BadThreads.java && java BadThreads 
-8680 

...所以我们成功地演示了并发性问题。当你试图证明这个问题时,你只有5次的运行就会变得“幸运” - 或者不幸。 :)

0

请勿使用静态int。使用AtomicInteger。它正是为这种情况而设计的。

如果你不想使用它,请使concursovolatile。你正在看到缓存的值。

+0

@xFunkyTimes专门用于*创建*并发问题,最有可能用于演示目的(或者仅仅是他们自己的理解)。但是,是的,AtomicIntegers是好的(如果使用正确)。 –

+0

然后他做了变量volatile后他应该怎么做才能真正解决问题?因为单独挥发是不够的。 – Voo