un blog de opiniones con mate lavado

tricky foreman

Today I was discussing threads with my fellow programmer Federico, just to conclude that threads are tricky and Java is not the exception.

Many of us are convinced that to use them safely, it is only question of adding a few synchronized declarations here and there to make the whole class “thread safe”

Well, as it usually happens with many things in life, it just happens is not that easy😛

And just to prove that I just made this multi threaded piece of shi^h^h^h code that may/may not do its work right depending on what tests are enabled and how are all them run, all of it whitout using any single synchronized block.

(In fact using “synchronized” blocks not only increases the risk of deadlocks but also creates bottlenecks -downgrading performance- so it is better to avoide them as much as possible)

Commens? Questions? Feel free to write them down here or email me!






package com.scriptorum.concurrence;

import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;

/**
 
 * This test is prepared to demonstrate how thread.start() and thread.join() work together to parallelize a task
 
 * Proceed as follows: 
 *  
 *  1) First, go through the code, read it, try to guess what will this code do when running
 *   2) Then, run only testWithoutJoin(), look at the results
 *  3) After that, run testWithJoin(), look at the results too
 *  4) Finally, run all the tests together several times, then compare the results you got each time
 *  with what you expected to happen before running
 *
 *  Comments/questions/sugerences are welcome, just drop me an email to gerardo@scriptorum.com.ar
 
 @author gerardo
 *
 */

public class ForemanTest {
  
  static int numberOfThreads = 20;
  static Thread threads [] new Thread[numberOfThreads];
  static AtomicInteger haveWorked = new AtomicInteger();
  
  @Test
  public void testWithoutJoin() {
    startWorking("WithoutJoin");
    evalResults();
  }

  @Test
  public void testWithJoin() {
    startWorking("WithJoin");
    startWaiting();
    evalResults();
  }

  private void evalResults() {
    if(haveWorked.get() < numberOfThreads) {
      System.out.println("What a bunch of lazy workers! Only " + haveWorked.get() " got your job done!");
    else if(haveWorked.get()==numberOfThreads) {
      System.out.println("Very well workers, all of you (" + haveWorked.get() " guys) got your job done before I got to leave!");
    else // haveWorked.get() > numberOfThreads) 
      System.out.println("Come on suckers, you're lying to me (I didn't hire " + haveWorked.get() " guys!)");
    }
  }
  
  public void startWorking(String string) {
    for(int i = 0; i < numberOfThreads; i++) {
      threads[inew Thread(new Worker(string+i));
      threads[i].start();
    }
  }
  
  public void startWaiting() {
    for(int i = 0; i < numberOfThreads; i++) {
      try {
        threads[i].join();
      catch (InterruptedException e) {
        // this code is not expected to run
        System.out.println("can't wait anymore;");
      }
    }
  }
  
  public class Worker implements Runnable {
    
    private String wrkId;
    
    public Worker(String wrkId) {
      this.wrkId = wrkId;
    }
    
    @Override
    public void run() {
      try {
        long waitingTime = new Random().nextInt(10000)+1
        System.out.println("Worker " 
            this.wrkId + " esperará " + waitingTime + " millis antes de terminar.");
        Thread.sleep(waitingTime);
        System.out.println("Worker " 
            this.wrkId + " terminó de esperar luego de " + waitingTime + " millis.");
        haveWorked.getAndAdd(1);
      
      catch (InterruptedException e) {
        // this code is not expected to run 
        System.out.println("Worker " this.wrkId + " ha sido interrumpido!");
      }
    }
  }
}


que opinas tu?

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s