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();
}
}
13 Réponses :
Vous manquez volatile code> mot-clé dans
OddTurn code> variable. Sans il n'y a pas de garantie que les threads voient la valeur réelle. P>
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 code> n'a pas d'importance. Les deux threads accèdent à différentes variables.
Je pense que le problème peut être que printoddd code> et
printempsven code> 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 code> sera visible dans l'autre thread. Essayez de faire le
Oddturn code> volatile pour le début. P>
Vous attendez et notifiant différents objets ( moniteurs em>). L'idée est que vous pouvez appeler Modifiez votre méthode et la méthode code> princente p> Ensuite, fournissez le obj.wait () code> pour attendre que quelqu'un fasse
obj.notify () code>, pendant que vous faites
obja.wait () code> et
objb.notify () code>. p>
printoddd code> à quelque chose comme p>
numberprinter code> avec un
verroue code> objet: p>
odd1
even2
odd3
even4
odd5
even6
odd7
even8
odd9
Il y a beaucoup de bugs dans le code. P>
Tout d'abord, les déclarations code> synchronisées code> n'ont aucun effet que ce soit. Vous créez deux instances de thread et chacune appelle uniquement ses propres méthodes. alors Donc, ce dont vous avez besoin est un autre objet qui contient l'état et les deux threads peuvent voir et utiliser. Utilisez synchronisé code> n'est utile que si Un autre thread em> peut appeler une méthode. P>
notifier () code> n'a aucun effet pour les mêmes raisons.
étrange.notifyall () code> n'atteint pas
même code> suspendu dans le
attendre () code>. p>.
synchronisé code>,
attendre () code> et
notifier () code> sur cette troisième instance. P>
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 Code> Package :)
J'ai fait de cette façon
J'ai utilisé un objet partagé pour contrôler l'ordre d'exécution
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.
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();
}
}
Votre code corrigé avec l'utilisation d'une interface de verrouillage: strong>
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
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(); } } }
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"); } }
Je l'ai mis en place d'une manière très simple, de 1 à 40>
Est-ce que ces devoirs? Si oui, ajoutez la balise "devoir" à votre question.
Pourquoi cet algorithme marqué est-il?