7
votes

Impression uniforme impair avec fil

Impression de numéro unimaire impair à l'aide de la classe de thread.Créer une classe de thread, deux instance du fil. On imitera le nombre impair et l'autre imprimera le nombre pair. Strong>

J'ai fait le codage suivant. Mais il s'agit d'un état de verrouillage mort. Quelqu'un peut-il expliquer ce que pourrait être la raison de cela? P>

public class NumberPrinter implements Runnable{
private String type;
private static boolean oddTurn=true;


public NumberPrinter(String type){
    this.type=type;
}
public void run() {
    int i=type.equals("odd")?1:2;
    while(i<10){
        if(type.equals("odd"))
            printOdd(i);
        if(type.equals("even"))
            printEven(i);
        i=i+2;
    }

}

private synchronized void printOdd(int i){
    while(!oddTurn){
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    System.out.println(type + i);
    oddTurn=false;
    notifyAll();
}

private synchronized  void printEven(int i){
    while(oddTurn){
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace(); 
        }
    }
    System.out.println(type + i);
    oddTurn=true;
    notifyAll();

}

public static void main(String[] s){
    Thread odd=new Thread(new NumberPrinter("odd"));
    Thread even=new Thread(new NumberPrinter("even"));
    odd.start();
    even.start();

}
}


2 commentaires

Est-ce que ces devoirs? Si oui, ajoutez la balise "devoir" à votre question.


Pourquoi cet algorithme marqué est-il?


13 Réponses :


0
votes

Vous manquez volatile mot-clé dans OddTurn variable. Sans il n'y a pas de garantie que les threads voient la valeur réelle.


3 commentaires

Merci pour votre réponse. Même après l'utilisation de volatils, obtenez également le même résultat. Ça va à l'impasse.


Voir d'autres réponses, j'ai raté le fait que vous avez deux objets, aucune synchronisation réelle n'est réalisée.


volatile n'a pas d'importance. Les deux threads accèdent à différentes variables.



1
votes

Je pense que le problème peut être que printoddd et printempsven Synchronisez sur différents verroues (les serrures d'instance d'objet du thread). Vous n'avez pas garanti que la variation de la variable statique Oddturn sera visible dans l'autre thread. Essayez de faire le Oddturn volatile pour le début.


0 commentaires

13
votes

Vous attendez et notifiant différents objets ( moniteurs em>).

L'idée est que vous pouvez appeler obj.wait () code> pour attendre que quelqu'un fasse obj.notify () code>, pendant que vous faites obja.wait () code> et objb.notify () code>. p>

Modifiez votre méthode printoddd code> à quelque chose comme p> xxx pré>

et la méthode code> princente p>

Ensuite, fournissez le numberprinter code> avec un verroue code> objet: p> xxx pré>

sortie: strong> p >

odd1
even2
odd3
even4
odd5
even6
odd7
even8
odd9


0 commentaires

4
votes

Il y a beaucoup de bugs dans le code.

Tout d'abord, les déclarations synchronisées n'ont aucun effet que ce soit. Vous créez deux instances de thread et chacune appelle uniquement ses propres méthodes. synchronisé n'est utile que si Un autre thread peut appeler une méthode.

alors notifier () n'a aucun effet pour les mêmes raisons. étrange.notifyall () n'atteint pas même suspendu dans le attendre () . .

Donc, ce dont vous avez besoin est un autre objet qui contient l'état et les deux threads peuvent voir et utiliser. Utilisez synchronisé , attendre () et notifier () sur cette troisième instance.


3 commentaires

Vous n'avez pas besoin de laisser l'objet commun à contenir n'importe quel état dans ce cas. Voir ma réponse.


C'est vrai, mais cela rend plus simple de voir quel état est partagé entre les deux threads. La programmation multithreadée est déjà complexe sans ajouter plus de complexité :-)


D'accord. Des tâches telles que celles-ci devraient, à moins qu'elles font partie de certaines devoirs, également codées à l'aide du document Java.Util.ConCurrent Package :)



1
votes

J'ai fait de cette façon xxx


0 commentaires

0
votes

J'ai utilisé un objet partagé pour contrôler l'ordre d'exécution xxx


0 commentaires

0
votes

Voici ma solution sans attendre ou notifier. attendre () et notifier () / notifier (),
Je ne vois aucune raison de les utiliser pour cette déclaration de problème. XXX


0 commentaires

2
votes

la même chose peut être résolu à l'aide de l'interface de verrouillage: strong>

NaturalOrder.java P>

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class EvenNumberLock implements Runnable {

    NaturalOrder naturalOrder;
    Lock lock;
    Condition condition;

    public EvenNumberLock(NaturalOrder naturalOrder, Lock lock, Condition condition) {
        this.naturalOrder = naturalOrder;
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        lock.lock();
        while (naturalOrder.currentNumber < 20) {
            while (naturalOrder.evenOdd != true) {
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            try {
                Thread.sleep(ThreadLocalRandom.current().nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (naturalOrder.currentNumber % 2 == 0) {
                System.out.println(naturalOrder.currentNumber);
            }
            naturalOrder.currentNumber++;
            naturalOrder.evenOdd = false;
            condition.signalAll();
        }
        lock.unlock();
    }
}


0 commentaires

0
votes

Votre code corrigé avec l'utilisation d'une interface de verrouillage: xxx


0 commentaires

0
votes
public class Number_Thread extends Thread {

String thread;
int limit;

public Number_Thread(String thread,int limit){
    this.thread=thread;
    this.limit=limit;
                                             }

Object lock=new Object();

public  void run()
{

    synchronized (lock) 
    {

          //------------------- "print even"--------------------//

      if(thread.equals("even"))
        {
            for (int i = 2; i <=limit; i+=2) 
            {

                 System.out.println(thread+" thread "+i);
            try {

            lock.wait(1000);
                 continue;

                }
              catch (InterruptedException e) {}
            }
            lock.notifyAll();
        }

         //------------------- "print odd"--------------------//

    if(thread.equals("odd"))
         {
         for (int i = 1; i <=limit; i+=2) 
             {
                System.out.println(thread+" thread  "+i);
            try {

                lock.wait(1000);
                    continue;
                }
            catch (InterruptedException e) {}
            }
            lock.notifyAll();
         }
      }
   }
}

     //------------------thread creater class------------------//
import java.util.Scanner;

public class Main_Thread {
private static Scanner s;
    public static void main(String[] args) throws InterruptedException {
        System.out.print("enter limit:\t ");
        s=new Scanner(System.in);
    int n=s.nextInt();
     s.close();
    Thread t1=new Number_Thread("even",n);
    Thread t2=new Number_Thread("odd",n);
    t2.start();
    Thread.sleep(100);
    t1.start();

 }

}
output for limit 5:enter limit:     5odd  thread 1
even thread 2
odd  thread  3
even thread 4
odd  thread  5

0 commentaires

0
votes

J'ai mis en œuvre de telle manière, sur la base de l'argument, aucun des threads sera engendré et sera le non respectif de la manière de Round Robin. I.e., si le nombre de threads est 3, le fil 1 imprimera 1,4 ...; Le fil 2 imprimera 2,5, ... et le fil 3 imprimera 3,6 ...

public class ThreadSynchronizer
{

    public static void main(String[] args)
    {
    // BASED ON THE ARGUMENT MULTIPLE THREADS WILL BE CREATED AND EACH WILL PRINT ITS RESPECTIVE NO
    // IE, IF THREAD COUNT IS 3, THREAD 1 WILL PRINT 1,4 ..., THREAD2 WILL PRINT 2,5,... AND THREAD3 WILL PRINT 3,6...
    // LIMITED THE DISPLAY TO 1000 NOS
    int threadCnt = Integer.parseInt(args[0]);

    ReentrantLock lckArray[] = new ReentrantLock[threadCnt + 1];

    for (int i = 0; i < threadCnt + 1; i++)
    {
        ReentrantLock lck = new ReentrantLock();
        lck.lock();
        lckArray[i] = lck;
    }

    for (int i = 0; i < threadCnt; i++)
    {
        Thread th = new Thread(new Printer(lckArray, i + 1));
        th.start();
    }

    for (int i = 1; i < threadCnt + 1; i++)
    {
        lckArray[i].unlock();

        while (!lckArray[i].isLocked())
        {

        }
    }
    lckArray[0].unlock();
    }
}

class Printer implements Runnable
{

    private ReentrantLock[] lckArray;
    private int index;

    Printer(ReentrantLock[] lckArray, int startValue)
    {
    this.lckArray = lckArray;
    this.index = startValue;
    }

    @Override public void run()
    {
    ReentrantLock prevLock = null;
    int printCounter = index;

    for (int counter = 0; printCounter <= 1000; counter++)
    {
        int remCounter = counter % lckArray.length;
        int incCounter = lckArray.length - remCounter;
        int indexPostion = index + incCounter;
        int curElementIndex = indexPostion % lckArray.length;

        lckArray[curElementIndex].lock();
        if (prevLock != null)
        prevLock.unlock();
        prevLock = lckArray[curElementIndex];

        if (curElementIndex == 0)
        {
        System.out.println("Printed by Thread " + index + " " + printCounter);
        printCounter = printCounter + lckArray.length - 1;
        }

    }

    if (prevLock != null)
    {
        if (prevLock.isHeldByCurrentThread())
        prevLock.unlock();
    }

    }

}


0 commentaires

0
votes

Programme pour deux threads, imprimez alternativement des nombres impairs et paires.

#Implégement en utilisant le concept "Verrouillage d'objet". P>

class Increment{
private int count;
    public void increment(){
        count++;
        System.out.println(Thread.currentThread().getName()+"::::::::::::::::::"+count);
    }
}


class SimpleThread extends Thread{
 
 Increment obj = null;
 
 SimpleThread(Increment obj){
    this.obj=obj;
 }  
 
 public void run(){
     try {
    Thread.sleep(100);
         while(true){
            synchronized(obj){
                   obj.increment();
                   Thread.sleep(1000);
                   obj.notify();
                   obj.wait();  
            }
         }
     } catch(InterruptedException ie) {
        ie.printStackTrace(); 
     }
 } 
 
}

public class Main
{
    public static void main(String[] args) {
        
        Increment increment = new Increment();
        SimpleThread t1 = new SimpleThread(increment);
        SimpleThread t2 = new SimpleThread(increment);
       
        t1.start();
        t2.start();

        System.out.println(Thread.currentThread().getName()+"::::::::::::::"+"Hello World");
        System.out.println(Runtime.getRuntime().availableProcessors()+"::::::::::::::"+"CORE SIZE");
    }
}


0 commentaires

0
votes

Je l'ai mis en place d'une manière très simple, de 1 à 40> xxx


0 commentaires