Visualizzazione dei risultati da 1 a 5 su 5

Discussione: Math.random genera sempre lo stesso numero

  1. #1
    Utente di HTML.it L'avatar di hopeway
    Registrato dal
    Sep 2017
    residenza
    Catania
    Messaggi
    37

    Math.random genera sempre lo stesso numero

    Salve, dovrei creare un programma dove si generino numeri casuali compresi tra -10 e 10. Io ho utilizzando la seguente sintassi:
    codice:
    int rand = (((int)(Math.random()))%21-10);
    Tuttavia mi genera sempre il numero -10. Come faccio ad integrare, prendendo esempio dal c, srand(time(NULL)) ?

  2. #2
    Quote Originariamente inviata da hopeway Visualizza il messaggio
    Salve, dovrei creare un programma dove si generino numeri casuali compresi tra -10 e 10. Io ho utilizzando la seguente sintassi:
    codice:
    int rand = (((int)(Math.random()))%21-10);
    Tuttavia mi genera sempre il numero -10.
    Perché fa prima il cast a int ! Nota infatti

    ( ((int)(Math.random())) %21-10)

    Insomma ... hai messo troppe parentesi .. e male. Oltretutto Math.random() restituisce valori tra 0 (compreso) e 1 (ESCLUSO). Quindi serve una moltiplicazione ... non il resto %.

    Quindi semplicemente:

    codice:
    int rand = (int) (Math.random() * 21) - 10;

    Prima esegue Math.random(), poi moltiplica per 21 (range 0...20,999999...) poi converte a int (range 0...20) poi sottrae 10 (range -10...10).
    Andrea, www.andbin.net – Senior Java developer – SCJP 5 (91%) – SCWCD 5 (94%)
    Il mio blog sulla programmazione

  3. #3
    Utente di HTML.it L'avatar di hopeway
    Registrato dal
    Sep 2017
    residenza
    Catania
    Messaggi
    37
    Quote Originariamente inviata da andbin Visualizza il messaggio
    ...
    Grazie mille, ho risolto!
    Avrei però un altri due dubbi: in pratica vorrei passare ai miei thread il nome (e lo faccio tramite .currentThread().getThread() ) ma da errore in compilazione (avevo visto questo esempio da codici del prof) e non riesco a capire se devo usarlo all'interno della classe che istanzia la variabile globale o all'interno dell'implementazione di runnable. Inoltre volevo sapere la differenza tra un metodo synchronized e no e se è necessario usarlo all'interno dei metodi di varGlobale. Vi allego il codice per semplicità

    codice:
    public class produttori {	public static void main(String args[]){
    		
    		varGlobale x = new varGlobale();
    		Thread product1 = new Thread(new products("PRODUTTORE1",x));
    		Thread product2 = new Thread(new products("PRODUTTORE2",x));
    		
    		product1.start();
    		product2.start();
    		try{
    			product1.join();
    		//	System.out.println(">> Join di procut 1...");
    			product2.join();
    		//	System.out.println(">> Join di product 2...");
    		}catch (InterruptedException e) {e.printStackTrace();}
    	}
    }
    
    
    class varGlobale {
    	int acc = 0;
    	
    	
    	public varGlobale () {
    		String threadName = Thread.currentThread().getName();
    		System.out.println(">>" + threadName + " instanzio la variabile globale..");
    	}
    	
    	public int getVar () { return acc; }
    	
    	public int sommaVar(int i){
    		acc+=i;
    		return acc;
    	}
    }
    
    
    class products implements Runnable {
    	
    	String threadName = Thread.currentThread().getName(); 
    	varGlobale x;
    	
    	public products (String threadName,varGlobale x) {
    		super(threadName);
    		this.x=x;
    		System.out.println("Costruttore di : "+ threadName + "istanzio acc");
    	}
    	
    	public void run(){
    		boolean ciclo = true;
    		while(ciclo){
    			int rand = (int) (Math.random() * 21) - 10;
    			System.out.println(">> Sono il thread: "+ threadName +" numero random generato " + rand );
    			if(rand == 0) {
    				System.out.println(">> Rand vale 0, esco!");
    				ciclo = false;
    			}
    			else {
    				x.sommaVar(rand);
    				System.out.println("Valore di acc attuale: " + x.getVar());
    			}
    		}
    	}
    	
    	
    }

  4. #4
    Quote Originariamente inviata da hopeway Visualizza il messaggio
    in pratica vorrei passare ai miei thread il nome (e lo faccio tramite .currentThread().getThread() )
    Il nome lo devi passare all'oggetto Thread ... non al tuo Runnable. Il name del java.lang.Thread, quello è il "vero" nome del thread!

    Mentre:

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

    non ha senso concettualmente, perché questa inizializzazione avviene quando il tuo products viene istanziato. E i due oggetti products li crei nel contesto del "main" thread! (quindi avrebbero lo stesso nome del main thread)

    Quote Originariamente inviata da hopeway Visualizza il messaggio
    ma da errore in compilazione
    Un errore in compilazione lo hai di sicuro, perché nel costruttore di products fai un:

    super(threadName);

    Ma products estende (implicitamente) Object, che NON ha certo un costruttore che riceve un String !

    Quote Originariamente inviata da hopeway Visualizza il messaggio
    Inoltre volevo sapere la differenza tra un metodo synchronized e no e se è necessario usarlo all'interno dei metodi di varGlobale.
    Acquisire un lock permette di avere atomicità, mutua-esclusione e garanzia della "visibilità" delle modifiche. Soltanto UN thread per volta può acquisire il lock.

    Un metodo "di istanza" (non static) synchronized acquisisce il lock sull'oggetto su cui il metodo è invocato.
    Un metodo "di classe" (static) synchronized acquisisce il lock sull'oggetto java.lang.Class associato a quella classe.


    E siccome lo stesso oggetto varGlobale è usato concorrentemente da due thread differenti, allora DEVI usare synchronized sui metodi di varGlobale.
    Perché acc+=i; di per sé NON è "atomico" quindi senza synchronized cosa succede .... boh, cose brutte ....
    E in ogni caso senza synchronized non avresti garanzia sulla "visibilità" delle modifiche da parte di altri thread.
    Andrea, www.andbin.net – Senior Java developer – SCJP 5 (91%) – SCWCD 5 (94%)
    Il mio blog sulla programmazione

  5. #5
    Utente di HTML.it L'avatar di hopeway
    Registrato dal
    Sep 2017
    residenza
    Catania
    Messaggi
    37
    Quote Originariamente inviata da andbin Visualizza il messaggio
    ..
    Grazie mille, sei stato gentilissimo e hai risolto tutti i miei dubbi in pieno! Potete chiudere

    Aggiungo, per completezza che , dato che volevo controllare quale thread stesse utilizzando i vari metodi ho aggiunto
    codice:
    String threadName = Thread.currentThread().getName();
    All'interno dei metodi synchronized

    codice:
    public synchronized int getVar () {        String threadName = Thread.currentThread().getName();
            System.out.println(">> SONO: "+threadName);
            return acc; }
        
        public synchronized int sommaVar(int i){
            String threadName = Thread.currentThread().getName();
            
            System.out.println("Sono il thread " + threadName + " e sommo acc="+acc+" ad i="+i);
            acc+=i;
            return acc;
        }
    e funziona correttamente inizializzando i thread come:

    codice:
    Thread product1 = new Thread(new products(x),"A");
    Che da in output il nome giusto assegnato nel main invece di "main" come capitava prima.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.