Autore Topic: Uso condiviso di un oggetto tra Uithread e un altro thread, semaforo ?  (Letto 649 volte)

Offline aeroxr1

  • Utente junior
  • **
  • Post: 76
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    galaxy nexus
  • Sistema operativo:
    window 8.1
Ciao,
mi chiedevo una cosa riguardante i semaforo. COme faccio a mettere un semaforo su un oggetto condiviso tra mainthread e ui thread ?

Mettiamo che usi i Semaphore di java.

Acquisisco il semaforo nel thread A, Uithread tenterà di prendere il semaforo, ma non riesce e si blocca.

Non si può fare una cosa del genere o sbaglio ?

Seconda domanda :
Guardando guide sulle surfaceview mi sono trovato davanti a questo uso del join, e non mi torna troppo :
Codice: [Seleziona]
  @Override
                    public void surfaceDestroyed(SurfaceHolder holder) {
                           boolean retry = true;
                           gameLoopThread.setRunning(false);
                           while (retry) {
                                  try {
                                        gameLoopThread.join();
                                        retry = false;
                                  } catch (InterruptedException e) {
                                  }
                           }
                    }
http://www.edu4java.com/en/androidgame/androidgame3.html

a cosa diavolo serve il while(retry) ? tanto retry non sarà sempre false appena il thread si sblocca dal join ?

Offline Gianluca.G

  • Nuovo arrivato
  • *
  • Post: 2
  • www.gianlucaghettini.net
  • Respect: 0
    • Github
    • gianlucaghettini
    • giangio82
    • ___Gianluca____
    • Mostra profilo
    • www.gianlucaghettini.net
  • Dispositivo Android:
    Samsung Duos S-7582
  • Play Store ID:
    Gianluca Ghettini
  • Sistema operativo:
    OS X 10.8
Re:Uso condiviso di un oggetto tra Uithread e un altro thread, semaforo ?
« Risposta #1 il: 15 Settembre 2015, 22:01:59 CEST »
0
Ciao,

allora il semaforo permette l'accesso mutualmente esclusivo ad una porzione di codice (in gergo chiamata sezione critica). Nel tuo caso hai il thread principale UI e un altro thread che tentano di accedere in modo concorrente ad uno stesso oggetto.

Chi arriva per primo entra, blocca il semaforo, fa quello che deve fare, esce e sblocca il semaforo.

Puoi instanziare il semaforo in questo modo. 1 significa che un solo thread per volta è ammeso.

Codice (Java): [Seleziona]
private final Semaphore lock = new Semaphore(1, true);
Poi puoi utilizzare i metodi seguenti:

Codice (Java): [Seleziona]
lock.Acquire();
// sezione critica
lock.Release();

Nella modalità sopra l'Acquire() è bloccante nel senso che se un thread trova il semaforo "rosso" resta bloccato alla chiamata Acquire() finchè l'altro thread non effettua il Release().

Esiste un'atra modalità, non bloccate, detta tryAcquire() nella quale se un thread trova il semaforo "rosso" non rimane bloccato in TryAcquire() ma riceve immediatamente un valore booleano: se è true significa che ha avuto accesso al semaforo, se è rosso significa che il semaforo è rosso e occupato. Il thread può quindi gestire la situazione senza mai bloccarsi e fare altro nel frattempo.

Codice (Java): [Seleziona]
boolean res = lock.TryAcquire();
if(res == true)
{
   // sezione critica
   lock.Release();
}


Seconda parte della domanda:
E' buona norma utilizzare il while() sempre assieme al Join() esattamente come mostrato nel codice. Il codice è corretto.
Il Join() è bloccante è vero, appena si esce setti il retry a false ed il while è trasparente.

Ma.. c'è un ma...

Il Join() può uscire anche per un altro motivo altro dal termine del Thread stesso. Se per qualsiasi motivo il tuo thread riceve un interrupt il Join() esce emettendo un InterruptException. Un thread che riceve un interrupt non necessariamente termina (dipende da come è implementato il thread), quindi è buona norma ricontrollare tramite il while(). Come noterai in caso di eccezione la variable NON viene settata a true. In sostanza il while() è necessario perchè il Join() potrebbe uscire per via dell'eccezione e non del "vero" termine del thread.


   
« Ultima modifica: 15 Settembre 2015, 22:04:51 CEST da Gianluca.G »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Uso condiviso di un oggetto tra Uithread e un altro thread, semaforo ?
« Risposta #2 il: 16 Settembre 2015, 07:57:54 CEST »
0
Seconda domanda :
Guardando guide sulle surfaceview mi sono trovato davanti a questo uso del join, e non mi torna troppo :

Questa parte del codice viene eseguita quando la surfaceview viene distrutta. Quello che fa è sostanzialmente richiedere l'arresto del thread di gameloop e attendere l'effettivo arresto prima di eseguire la vera e propria distruzione.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store