J'essaie de créer deux threads, un thread affiche même des nombres entiers de 0 à 10, un thread affiche des nombres entiers impairs de 1 à 11. Le code suivant convient-il à la conception de ce programme?
public class Mythread {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
t.start();
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(int i=0;i<11;i++){
if(i%2 == 1)
System.out.println(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=0;i<11;i++){
if(i%2 == 0)
System.out.println(i);
}
}
}
Je voudrais juste changer quelques détails (pas besoin d'utiliser l'opérateur modulo ici ...):
public class Mythread {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(int i=0;i<11;i+=2) {
System.out.println(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=11;i+=2) {
System.out.println(i);
}
}
}
@aymeric answer n'imprimera pas les nombres dans leur ordre naturel, mais ce code le sera. Explication à la fin.
public class Driver {
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
for (int itr = 1; itr < 51; itr = itr + 2) {
synchronized (lock) {
System.out.print(" " + itr);
try {
lock.notify();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
for (int itr = 2; itr < 51; itr = itr + 2) {
synchronized (lock) {
System.out.print(" " + itr);
try {
lock.notify();
if(itr==50)
break;
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
try {
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("\nPrinting over");
} catch (Exception e) {
}
}
}
Afin d’y parvenir, les méthodes d’exécution des deux threads ci-dessus doivent être appelées les unes après les autres, c’est-à-dire qu’elles doivent être synchronisées et que je parviens à cela avec des verrous.
Le code fonctionne comme suit: t1.run affiche le nombre impair et informe tout thread en attente qu'il va libérer le verrou, puis passe en état d'attente.
À ce stade, t2.run est appelé, il affiche le numéro pair suivant, informe les autres threads qu'il est sur le point de libérer le verrou qu'il détient, puis passe à l'état d'attente.
Cela continue jusqu'à ce que l'itr dans t2.run () atteigne 50. À ce stade, notre objectif est atteint et nous devons éliminer ces deux threads.
En cassant, j'évite d'appeler lock.wait () dans t2.run et le thread t2 est donc arrêté, le contrôle passe maintenant à t1.run puisqu'il attendait l'acquisition du verrou; mais ici, sa valeur sera> 51 et nous sortirons de sa course (), fermant ainsi le fil.
Si break n'est pas utilisé dans t2.run (), nous verrons les numéros 1 à 50 à l'écran, mais les deux threads entreront dans une situation de blocage et resteront en attente.
package javaapplication45;
public class JavaApplication45 extends Thread {
public static void main(String[] args) {
//even numbers
Thread t1 = new Thread() {
public void run() {
for (int i = 1; i <= 20; i++) {
if (i % 2 == 0) {
System.out.println("even thread " + i);
}
}
}
};
t1.start();
//odd numbers
Thread t2 = new Thread() {
public void run() {
for (int i = 1; i <= 20; i++) {
if (i % 2 != 0) {
System.out.println("odd thread " + i);
}
}
}
};
t2.start();
}
}
Vous trouverez ci-dessous le code qui utilise le verrouillage sur un objet partagé portant le numéro à imprimer. Cela garantit également la séquence contrairement à la solution ci-dessus.
public class MultiThreadPrintNumber {
int i = 1;
public synchronized void printNumber(String threadNm) throws InterruptedException{
if(threadNm.equals("t1")){
if(i%2 == 1){
System.out.println(Thread.currentThread().getName()+"--"+ i++);
notify();
} else {
wait();
}
} else if(threadNm.equals("t2")){
if(i%2 == 0){
System.out.println(Thread.currentThread().getName()+"--"+ i++);
notify();
} else {
wait();
}
}
}
public static void main(String[] args) {
final MultiThreadPrintNumber obj = new MultiThreadPrintNumber();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
while(obj.i <= 10){
obj.printNumber(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("done t1");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
while(obj.i <=10){
obj.printNumber(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("done t2");
}
});
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}
La sortie ressemblera à ceci: T1--1 T2--2 T1–3 T2–4 T1–5 .t1-7 t2--8 t1--9 t2--10 fait t2 fait t1
Oui c'est bon. Mais dans ce cas, je ne pense pas que vous ayez besoin de 2 threads, car l’opération est simple. Cependant, si vous pratiquez des discussions, tout va bien.
Forfait simultané:
import Java.util.concurrent.ExecutorService;
import Java.util.concurrent.Executors;
import Java.util.concurrent.Future;
import Java.util.concurrent.locks.Condition;
import Java.util.concurrent.locks.Lock;
import Java.util.concurrent.locks.ReentrantLock;
//=========== Task1 class prints odd =====
class TaskClass1 implements Runnable
{
private Condition condition;
private Lock lock;
boolean exit = false;
int i;
TaskClass1(Condition condition,Lock lock)
{
this.condition = condition;
this.lock = lock;
}
@Override
public void run() {
try
{
lock.lock();
for(i = 1;i<11;i++)
{
if(i%2 == 0)
{
condition.signal();
condition.await();
}
if(i%2 != 0)
{
System.out.println(Thread.currentThread().getName()+" == "+i);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
lock.unlock();
}
}
}
//==== Task2 : prints even =======
class TaskClass2 implements Runnable
{
private Condition condition;
private Lock lock;
boolean exit = false;
TaskClass2(Condition condition,Lock lock)
{
this.condition = condition;
this.lock = lock;
}
@Override
public void run() {
int i;
// TODO Auto-generated method stub
try
{
lock.lock();
for(i = 2;i<11;i++)
{
if(i%2 != 0)
{
condition.signal();
condition.await();
}
if(i%2 == 0)
{
System.out.println(Thread.currentThread().getName()+" == "+i);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
lock.unlock();
}
}
}
public class OddEven {
public static void main(String[] a)
{
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Future future1;
Future future2;
ExecutorService executorService = Executors.newFixedThreadPool(2);
future1 = executorService.submit(new TaskClass1(condition,lock));
future2 = executorService.submit(new TaskClass2(condition,lock));
executorService.shutdown();
}
}
Je voudrais aussi envisager d’utiliser Java Concurrency si vous souhaitez des alternatives. Certaines des fonctionnalités fournies dans le package Java Concurrency offrent un niveau d'abstraction plus élevé que l'utilisation de la classe Thread directement et fournissent ainsi davantage de fonctionnalités.
Dans votre cas particulier, ce que vous faites est tout à fait raisonnable mais l’ordre d’impression de ces chiffres est-il important? Voulez-vous un peu avant les cotes? Ce genre de questions indiquerait mieux la conception qui répond le mieux à vos besoins.
Pas la réponse pour le problème ci-dessus mais sur les lignes similaires.
Programme pour imprimer les éléments du tableau de manière séquentielle mais utiliser deux threads différents pour imprimer les éléments adjacents
import Java.util.logging.Level;
import Java.util.logging.Logger;
/**
*
* @author ntv
*/
public class PrintLAternateNumber {
public static void main(String[] args) {
int [] num = {1,2,3,4,5,6};
Printer p = new Printer();
Thread t1 = new Thread(new Thread1(num, p), "Thread1");
Thread t2 = new Thread(new Thread2(num, p), "Thread2");
t1.start();
t2.start();
}
}
class Thread1 implements Runnable {
int [] num;
Printer p ;
public Thread1(int[] num, Printer p) {
this.num = num;
this.p = p;
}
public void run() {
try {
print();
} catch (InterruptedException ex) {
Logger.getLogger(Thread1.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void print() throws InterruptedException {
int i = 1;
while(i < num.length) {
synchronized(num) {
while (p.evenPrinted) {
num.wait();
}
}
synchronized(num) {
p.printEven(Thread.currentThread().getName(), num[i]);
i= i + 2;
num.notifyAll();
}
}
}
}
class Thread2 implements Runnable {
int [] num;
Printer p ;
public Thread2(int[] num, Printer p) {
this.num = num;
this.p = p;
}
public void run() {
try {
print();
} catch (InterruptedException ex) {
Logger.getLogger(Thread2.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void print() throws InterruptedException {
int i = 0;
while(i < num.length) {
synchronized(num) {
while (!p.evenPrinted) {
num.wait();
}
}
synchronized(num) {
p.printOdd(Thread.currentThread().getName(), num[i]);
i = i + 2;
num.notifyAll();
}
}
}
}
class Printer {
boolean evenPrinted = true;
void printEven(String threadName , int i) {
System.out.println(threadName + "," + i);
evenPrinted = true;
}
void printOdd(String threadName , int i) {
System.out.println(threadName + "," + i);
evenPrinted = false;
}
}
package thread;
import org.hibernate.annotations.Synchronize;
class PrintOdd implements Runnable {
int count = -1;
private Object common;
PrintOdd(Object common) {
this.common = common;
}
@Override
public void run() {
synchronized (common) {
while (count < 1000) {
try {
common.notifyAll();
System.out.println(count += 2);
common.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
class PrintEven implements Runnable {
int count = 0;
private Object common;
PrintEven(Object common) {
this.common = common;
}
@Override
public void run() {
synchronized (common) {
while (count < 1000) {
try {
common.notifyAll();
System.out.println(count += 2);
common.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class PrintNatural {
public static void main(String args[]) {
Object obj = new Object();
Runnable r = new PrintOdd(obj);
Thread printOdd = new Thread(r);
Runnable r2 = new PrintEven(obj);
Thread printEven = new Thread(r2);
printOdd.start();
printEven.start();
}
}
Nos numéros seront imprimés dans l'ordre
Main class
===========
package com.thread;
import Java.util.concurrent.atomic.AtomicInteger;
public class StartThread {
static AtomicInteger no = new AtomicInteger(1);
public static void main(String[] args) {
Odd oddObj = new Odd();
Thread odd = new Thread(oddObj);
Thread even = new Thread(new Even(oddObj));
odd.start();
even.start();
}
}
Odd Thread
===========
package com.thread;
public class Odd implements Runnable {
@Override
public void run() {
while (StartThread.no.get() < 20) {
synchronized (this) {
System.out.println("Odd=>" + StartThread.no.get());
StartThread.no.incrementAndGet();
try {
this.notify();
if(StartThread.no.get() == 20)
break;
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Even Thread
===========
package com.thread;
public class Even implements Runnable {
Odd odd;
public Even(Odd odd) {
this.odd = odd;
}
@Override
public void run() {
while (StartThread.no.get() < 20) {
synchronized (odd) {
System.out.println("Even=>" + StartThread.no.get());
StartThread.no.incrementAndGet();
odd.notifyAll();
try {
odd.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output (Nos are printed in sequential)
======
Odd=>1
Even=>2
Odd=>3
Even=>4
Odd=>5
Even=>6
Odd=>7
Even=>8
Odd=>9
Even=>10
Odd=>11
Even=>12
Odd=>13
Even=>14
Odd=>15
Even=>16
Odd=>17
Even=>18
Odd=>19
package com.example;
public class MyClass {
static int mycount=0;
static Thread t;
static Thread t2;
public static void main(String[] arg)
{
t2=new Thread(new Runnable() {
@Override
public void run() {
System.out.print(mycount++ + " even \n");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(mycount>25)
System.exit(0);
run();
}
});
t=new Thread(new Runnable() {
@Override
public void run() {
System.out.print(mycount++ + " odd \n");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(mycount>26)
System.exit(0);
run();
}
});
t.start();
t2.start();
}
}
public class OddEvenPrinetr {
private static Object printOdd = new Object();
public static void main(String[] args) {
Runnable oddPrinter = new Runnable() {
int count = 1;
@Override
public void run() {
while(true){
synchronized (printOdd) {
if(count >= 101){
printOdd.notify();
return;
}
System.out.println(count);
count = count + 2;
try {
printOdd.notify();
printOdd.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Runnable evenPrinter = new Runnable() {
int count = 0;
@Override
public void run() {
while(true){
synchronized (printOdd) {
printOdd.notify();
if(count >= 100){
return;
}
count = count + 2;
System.out.println(count);
printOdd.notify();
try {
printOdd.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
new Thread(oddPrinter).start();
new Thread(evenPrinter).start();
}
}
public class ThreadExample {
Object lock = new Object();
class ThreadEven implements Runnable {
@Override
public void run() {
int i = 2;
while (i <= 20) {
synchronized (lock) {
System.out.println(i + " ");
i = i + 2;
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class ThreadOdd implements Runnable {
@Override
public void run() {
int i = 1;
while (i <= 20) {
synchronized (lock) {
System.out.println(i + " ");
i = i + 2;
try {
lock.notify();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String args[]) {
ThreadExample example = new ThreadExample();
ThreadExample.ThreadOdd odd = example.new ThreadOdd();
ThreadExample.ThreadEven even = example.new ThreadEven();
Thread oT = new Thread(odd);
Thread eT = new Thread(even);
oT.start();
eT.start();
}
classe publique ConsecutiveNumberPrint {
private static class NumberGenerator {
public int MAX = 100;
private volatile boolean evenNumberPrinted = true;
public NumberGenerator(int max) {
this.MAX = max;
}
public void printEvenNumber(int i) throws InterruptedException {
synchronized (this) {
if (evenNumberPrinted) {
wait();
}
System.out.println("e = \t" + i);
evenNumberPrinted = !evenNumberPrinted;
notify();
}
}
public void printOddNumber(int i) throws InterruptedException {
synchronized (this) {
if (!evenNumberPrinted) {
wait();
}
System.out.println("o = \t" + i);
evenNumberPrinted = !evenNumberPrinted;
notify();
}
}
}
private static class EvenNumberGenerator implements Runnable {
private NumberGenerator numberGenerator;
public EvenNumberGenerator(NumberGenerator numberGenerator) {
this.numberGenerator = numberGenerator;
}
@Override
public void run() {
for(int i = 2; i <= numberGenerator.MAX; i+=2)
try {
numberGenerator.printEvenNumber(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class OddNumberGenerator implements Runnable {
private NumberGenerator numberGenerator;
public OddNumberGenerator(NumberGenerator numberGenerator) {
this.numberGenerator = numberGenerator;
}
@Override
public void run() {
for(int i = 1; i <= numberGenerator.MAX; i+=2) {
try {
numberGenerator.printOddNumber(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
NumberGenerator numberGenerator = new NumberGenerator(100);
EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(numberGenerator);
OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(numberGenerator);
new Thread(oddNumberGenerator).start();
new Thread(evenNumberGenerator).start();
}
}
paquet p.Threads;
public class PrintEvenAndOddNum {
private Object obj = new Object();
private static final PrintEvenAndOddNum peon = new PrintEvenAndOddNum();
private PrintEvenAndOddNum(){}
public static PrintEvenAndOddNum getInstance(){
return peon;
}
public void printOddNum() {
for(int i=1;i<10;i++){
if(i%2 != 0){
synchronized (obj) {
System.out.println(i);
try {
System.out.println("oddNum going into waiting state ....");
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("resume....");
obj.notify();
}
}
}
}
public void printEvenNum() {
for(int i=1;i<11;i++){
if(i%2 == 0){
synchronized(obj){
System.out.println(i);
obj.notify();
try {
System.out.println("evenNum going into waiting state ....");
obj.wait();
System.out.println("Notifying waiting thread ....");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
public class MyThread {
public static void main(String[] args) {
// TODO Auto-generated method stub
Threado o =new Threado();
o.start();
Threade e=new Threade();
e.start();
}
}
class Threade extends Thread{
public void run(){
for(int i=2;i<10;i=i+2)
System.out.println("evens "+i);
}
}
class Threado extends Thread{
public void run(){
for(int i=1;i<10;i=i+2)
System.out.println("odds "+i);
}
}
SORTIE: -
cotes 1 cotes 3 .__ cotes 5 cotes 7 cotes 9
public class EvenOddNumberPrintUsingTwoThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0) {
System.out.println("Even : " + i);
}
}
}
};
Thread t2 = new Thread() {
// int i=0;
public void run() {
for (int i = 0; i <= 10; i++) {
if (i % 2 == 1) {
System.out.println("Odd : " + i);
}
}
}
};
t1.start();
t2.start();
}
}
public class ThreadClass {
volatile int i = 1;
volatile boolean state=true;
synchronized public void printOddNumbers(){
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+i);
state = false;
i++;
notifyAll();
}
synchronized public void printEvenNumbers(){
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+i);
state = true;
i++;
notifyAll();
}
}
Ensuite, appelez la classe ci-dessus comme ceci
// I am ttying to print 10 values.
ThreadClass threadClass=new ThreadClass();
Thread t1=new Thread(){
int k=0;
@Override
public void run() {
while (k<5) {
threadClass.printOddNumbers();
k++;
}
}
};
t1.setName("Thread1");
Thread t2=new Thread(){
int j=0;
@Override
public void run() {
while (j<5) {
threadClass.printEvenNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
out mis:
System.out: Thread1 1
System.out: Thread2 2
System.out: Thread1 3
System.out: Thread2 4
System.out: Thread1 5
System.out: Thread2 6
System.out: Thread1 7
System.out: Thread2 8
System.out: Thread1 9
System.out: Thread2 10
À peu près tout ce qui est nécessaire si vous êtes invité à imprimer des nombres pairs impairs de manière synchronisée.
public class ThreadingOddEvenNumbers {
void main(String[] args) throws InterruptedException {
Printer printer = new Printer(57);
Thread t1 = new Thread(new MyRunner(printer, true), "EvenPrinter");
Thread t2 = new Thread(new MyRunner(printer, false), "OddPrinter");
t1.start();
t2.start();
t1.join();
t2.join();
}
}
class MyRunner implements Runnable {
private Printer p;
private boolean evenProperty;
public MyRunner(Printer p, boolean evenNess) {
this.p = p;
evenProperty = evenNess;
}
public void run() {
try {
print();
} catch (InterruptedException ex) {
System.out.println(this.getClass().getName() + " "
+ ex.getMessage());
}
}
public void print() throws InterruptedException {
while (!p.isJobComplete()) {
synchronized (p) {
if (evenProperty)
while (p.isEvenPrinted()) {
System.out.println("wait by: "
+ Thread.currentThread().getName());
p.wait();
if (p.isJobComplete())
break;
}
else
while (!p.isEvenPrinted()) {
System.out.println("wait by: "
+ Thread.currentThread().getName());
p.wait();
if (p.isJobComplete())
break;
}
}
synchronized (p) {
if (evenProperty)
p.printEven(Thread.currentThread().getName());
else
p.printOdd(Thread.currentThread().getName());
p.notifyAll();
System.out.println("notify called: by: "
+ Thread.currentThread().getName());
}
}
}
}
class Printer {
private volatile boolean evenPrinted;
private volatile boolean jobComplete;
private int limit;
private int counter;
public Printer(int lim) {
limit = lim;
counter = 1;
evenPrinted = true;
jobComplete = false;
}
public void printEven(String threadName) {
System.out.println(threadName + "," + counter);
incrCounter();
evenPrinted = true;
}
public void printOdd(String threadName) {
System.out.println(threadName + "," + counter);
incrCounter();
evenPrinted = false;
}
private void incrCounter() {
counter++;
if (counter >= limit)
jobComplete = true;
}
public int getLimit() {
return limit;
}
public boolean isEvenPrinted() {
return evenPrinted;
}
public boolean isJobComplete() {
return jobComplete;
}
}