Печать Even and Odd с использованием двух потоков в Java
Я попробовал код ниже. Я взял этот кусок кода из какой-то другой статьи, которая правильна в соответствии с автором. Но когда я пытаюсь работать, это не дает мне точного результата.
Это в основном для непрерывной печати четных и нечетных значений.
public class PrintEvenOddTester {
public static void main(String ... args){
Printer print = new Printer(false);
Thread t1 = new Thread(new TaskEvenOdd(print));
Thread t2 = new Thread(new TaskEvenOdd(print));
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
int number=1;
Printer print;
TaskEvenOdd(Printer print){
this.print = print;
}
@Override
public void run() {
System.out.println("Run method");
while(number<10){
if(number%2 == 0){
System.out.println("Number is :"+ number);
print.printEven(number);
number+=2;
}
else {
System.out.println("Number is :"+ number);
print.printOdd(number);
number+=2;
}
}
}
}
class Printer {
boolean isOdd;
Printer(boolean isOdd){
this.isOdd = isOdd;
}
synchronized void printEven(int number) {
while(isOdd){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even:"+number);
isOdd = true;
notifyAll();
}
synchronized void printOdd(int number) {
while(!isOdd){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Odd:"+number);
isOdd = false;
notifyAll();
}
}
Может кто-нибудь помочь мне в исправлении этого?
ИЗМЕНИТЬ
Ожидаемый результат:
Odd: 1
Даже: 2
Нечетный: 3
Даже: 4
Странно: 5
Даже: 6
Странно: 7
Даже: 8
Нечетный: 9
Ответы
Ответ 1
Нашел решение. Кто-то, кто ищет решение этой проблемы, может ссылаться: -)
public class PrintEvenOddTester {
public static void main(String... args) {
Printer print = new Printer();
Thread t1 = new Thread(new TaskEvenOdd(print, 10, false));
Thread t2 = new Thread(new TaskEvenOdd(print, 10, true));
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
private int max;
private Printer print;
private boolean isEvenNumber;
TaskEvenOdd(Printer print, int max, boolean isEvenNumber) {
this.print = print;
this.max = max;
this.isEvenNumber = isEvenNumber;
}
@Override
public void run() {
//System.out.println("Run method");
int number = isEvenNumber == true ? 2 : 1;
while (number <= max) {
if (isEvenNumber) {
//System.out.println("Even :"+ Thread.currentThread().getName());
print.printEven(number);
//number+=2;
} else {
//System.out.println("Odd :"+ Thread.currentThread().getName());
print.printOdd(number);
// number+=2;
}
number += 2;
}
}
}
class Printer {
boolean isOdd = false;
synchronized void printEven(int number) {
while (isOdd == false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even:" + number);
isOdd = false;
notifyAll();
}
synchronized void printOdd(int number) {
while (isOdd == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Odd:" + number);
isOdd = true;
notifyAll();
}
}
Это дает результат, например:
Odd:1
Even:2
Odd:3
Even:4
Odd:5
Even:6
Odd:7
Even:8
Odd:9
Even:10
Ответ 2
Вот код, который я заставил его работать через один класс
package com.learn.thread;
public class PrintNumbers extends Thread {
volatile static int i = 1;
Object lock;
PrintNumbers(Object lock) {
this.lock = lock;
}
public static void main(String ar[]) {
Object obj = new Object();
// This constructor is required for the identification of wait/notify
// communication
PrintNumbers odd = new PrintNumbers(obj);
PrintNumbers even = new PrintNumbers(obj);
odd.setName("Odd");
even.setName("Even");
odd.start();
even.start();
}
@Override
public void run() {
while (i <= 10) {
if (i % 2 == 0 && Thread.currentThread().getName().equals("Even")) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " - "
+ i);
i++;
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (i % 2 == 1 && Thread.currentThread().getName().equals("Odd")) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " - "
+ i);
i++;
lock.notify();
}
}
}
}
}
Вывод:
Odd - 1
Even - 2
Odd - 3
Even - 4
Odd - 5
Even - 6
Odd - 7
Even - 8
Odd - 9
Even - 10
Odd - 11
Ответ 3
Используйте эту следующую очень простую функцию JAVA 8 Runnable Class
public class MultiThreadExample {
static AtomicInteger atomicNumber = new AtomicInteger(1);
public static void main(String[] args) {
Runnable print = () -> {
while (atomicNumber.get() < 10) {
synchronized (atomicNumber) {
if ((atomicNumber.get() % 2 == 0) && "Even".equals(Thread.currentThread().getName())) {
System.out.println("Even" + ":" + atomicNumber.getAndIncrement());
} else if ((atomicNumber.get() % 2 != 0) && "Odd".equals(Thread.currentThread().getName())) {
System.out.println("Odd" + ":" + atomicNumber.getAndIncrement());
}
}
}
};
Thread t1 = new Thread(print);
t1.setName("Even");
t1.start();
Thread t2 = new Thread(print);
t2.setName("Odd");
t2.start();
}
}
Ответ 4
Эта программа может быть написана в два ways-
- Использование ожидания и уведомления для связи между потоками. Но недостатком этого является то, что если количество потоков увеличивается более двух, то оно не может быть использовано.
- Использование Java Semaphore для взаимодействия между потоками. Это более расширяемое и может быть изменено, даже если вопрос будет дополнительно изменен примерно на 3 темы -
пакет com.effectivecorejava; import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
//We dont want the even number printed first so the initial permit for this semaphore is 0.
Semaphore evenSemaphore = new Semaphore(0);
//We want to print the odd number first so the initial permit for this semaphore is 1.
Semaphore oddSemaphore = new Semaphore(1);
PrintOddNumber printOddNumber = new PrintOddNumber(evenSemaphore, oddSemaphore);
PrintEvenNumber printEvenNumber = new PrintEvenNumber(evenSemaphore, oddSemaphore);
new Thread(printOddNumber, "Print Odd").start();
new Thread(printEvenNumber, "Print Odd").start();
}
}
class PrintEvenNumber implements Runnable {
Semaphore sempahoreEven;
Semaphore sempahoreOdd;
public PrintEvenNumber(Semaphore sempahoreEven, Semaphore sempahoreOdd) {
super();
this.sempahoreEven = sempahoreEven;
this.sempahoreOdd = sempahoreOdd;
}
@Override
public void run() {
for (int i = 2;; i = i + 2) {
try {
//This will decrement the permit used by the even semaphore to 0.
sempahoreEven.acquire();
System.out.println(i);
//This will increment the permit used by odd semaphore by 1.
sempahoreOdd.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class PrintOddNumber implements Runnable {
Semaphore sempahoreEven;
Semaphore sempahoreOdd;
public PrintOddNumber(Semaphore sempahoreEven, Semaphore sempahoreOdd) {
this.sempahoreEven = sempahoreEven;
this.sempahoreOdd = sempahoreOdd;
}
@Override
public void run() {
for (int i = 1;; i = i + 2) {
try {
//This will decrement the permit used by the odd semaphore to 0.
sempahoreOdd.acquire();
Thread.sleep(1000);
System.out.println(i);
//This will increment the permit used by even semaphore by 1.
sempahoreEven.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Ответ 5
private Object lock = new Object();
private volatile boolean isOdd = false;
public void generateEvenNumbers(int number) throws InterruptedException {
synchronized (lock) {
while (isOdd == false)
{
lock.wait();
}
System.out.println(number);
isOdd = false;
lock.notifyAll();
}
}
public void generateOddNumbers(int number) throws InterruptedException {
synchronized (lock) {
while (isOdd == true) {
lock.wait();
}
System.out.println(number);
isOdd = true;
lock.notifyAll();
}
}
Ответ 6
Этот код также будет работать нормально.
class Thread1 implements Runnable {
private static boolean evenFlag = true;
public synchronized void run() {
if (evenFlag == true) {
printEven();
} else {
printOdd();
}
}
public void printEven() {
for (int i = 0; i <= 10; i += 2) {
System.out.println(i+""+Thread.currentThread());
}
evenFlag = false;
}
public void printOdd() {
for (int i = 1; i <= 11; i += 2) {
System.out.println(i+""+Thread.currentThread());
}
evenFlag = true;
}
}
public class OddEvenDemo {
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread td1 = new Thread(t1);
Thread td2 = new Thread(t1);
td1.start();
td2.start();
}
}
Ответ 7
То же самое можно сделать с интерфейсом Lock:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NumberPrinter implements Runnable {
private Lock lock;
private Condition condition;
private String type;
private static boolean oddTurn = true;
public NumberPrinter(String type, Lock lock, Condition condition) {
this.type = type;
this.lock = lock;
this.condition = condition;
}
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 void printOdd(int i) {
// synchronized (lock) {
lock.lock();
while (!oddTurn) {
try {
// lock.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + " " + i);
oddTurn = false;
// lock.notifyAll();
condition.signalAll();
lock.unlock();
}
// }
private void printEven(int i) {
// synchronized (lock) {
lock.lock();
while (oddTurn) {
try {
// lock.wait();
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(type + " " + i);
oddTurn = true;
// lock.notifyAll();
condition.signalAll();
lock.unlock();
}
// }
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread odd = new Thread(new NumberPrinter("odd", lock, condition));
Thread even = new Thread(new NumberPrinter("even", lock, condition));
odd.start();
even.start();
}
}
Ответ 8
Это самое простое решение для этой проблемы.
public class OddEven implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 1; i <= 10; i++) {
synchronized (this) {
if (i % 2 == 0 && Thread.currentThread().getName().equals("t2")) {
try {
notifyAll();
System.out.println("Even Thread : " + i);
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (i % 2 != 0
&& Thread.currentThread().getName().equals("t1")) {
try {
notifyAll();
System.out.println("Odd Thread : " + i);
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
OddEven obj = new OddEven();
Thread t1 = new Thread(obj, "t1");
Thread t2 = new Thread(obj, "t2");
t1.start();
t2.start();
}
}
Ответ 9
import java.util.concurrent.atomic.AtomicInteger;
public class PrintEvenOddTester {
public static void main(String ... args){
Printer print = new Printer(false);
Thread t1 = new Thread(new TaskEvenOdd(print, "Thread1", new AtomicInteger(1)));
Thread t2 = new Thread(new TaskEvenOdd(print,"Thread2" , new AtomicInteger(2)));
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
Printer print;
String name;
AtomicInteger number;
TaskEvenOdd(Printer print, String name, AtomicInteger number){
this.print = print;
this.name = name;
this.number = number;
}
@Override
public void run() {
System.out.println("Run method");
while(number.get()<10){
if(number.get()%2 == 0){
print.printEven(number.get(),name);
}
else {
print.printOdd(number.get(),name);
}
number.addAndGet(2);
}
}
}
class Printer {
boolean isEven;
public Printer() { }
public Printer(boolean isEven) {
this.isEven = isEven;
}
synchronized void printEven(int number, String name) {
while (!isEven) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+": Even:" + number);
isEven = false;
notifyAll();
}
synchronized void printOdd(int number, String name) {
while (isEven) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+": Odd:" + number);
isEven = true;
notifyAll();
}
}
Ответ 10
Другой вопрос был закрыт как дубликат этого. Я думаю, что мы можем спокойно избавиться от "четной или нечетной" проблемы и использовать конструкцию wait/notify
следующим образом:
public class WaitNotifyDemoEvenOddThreads {
/**
* A transfer object, only use with proper client side locking!
*/
static final class LastNumber {
int num;
final int limit;
LastNumber(int num, int limit) {
this.num = num;
this.limit = limit;
}
}
static final class NumberPrinter implements Runnable {
private final LastNumber last;
private final int init;
NumberPrinter(LastNumber last, int init) {
this.last = last;
this.init = init;
}
@Override
public void run() {
int i = init;
synchronized (last) {
while (i <= last.limit) {
while (last.num != i) {
try {
last.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " prints: " + i);
last.num = i + 1;
i += 2;
last.notify();
}
}
}
}
public static void main(String[] args) {
LastNumber last = new LastNumber(0, 10); // or 0, 1000
NumberPrinter odd = new NumberPrinter(last, 1);
NumberPrinter even = new NumberPrinter(last, 0);
new Thread(odd, "o").start();
new Thread(even, "e").start();
}
}
Ответ 11
Simpler Version in Java 8:
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
Runnable odd = () -> {
for (int i = 1; i <= 10;) {
if(EvenOddPrinter.flag) {
System.out.println(i);
i+=2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
};
Runnable even = () -> {
for (int i = 2; i <= 10;) {
if(!EvenOddPrinter.flag) {
System.out.println(i);
i+=2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
};
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}
Ответ 12
package pkgscjp;
public class OddPrint implements Runnable {
public static boolean flag = true;
public void run() {
for (int i = 1; i <= 99;) {
if (flag) {
System.out.println(i);
flag = false;
i = i + 2;
}
}
}
}
package pkgscjp;
public class EvenPrint implements Runnable {
public void run() {
for (int i = 2; i <= 100;) {
if (!OddPrint.flag) {
System.out.println(i);
OddPrint.flag = true;
i = i + 2;
}
}
}
}
package pkgscjp;
public class NaturalNumberThreadMain {
public static void main(String args[]) {
EvenPrint ep = new EvenPrint();
OddPrint op = new OddPrint();
Thread te = new Thread(ep);
Thread to = new Thread(op);
to.start();
te.start();
}
}
Ответ 13
Я сделал это таким образом, при печати с использованием двух потоков мы не можем предсказать последовательность, в которой поток сначала будет выполнено, чтобы преодолеть эту ситуацию, мы должны синхронизировать общий ресурс, в
в моем случае используется функция печати, к которой обращаются два потока.
class Printoddeven{
public synchronized void print(String msg) {
try {
if(msg.equals("Even")) {
for(int i=0;i<=10;i+=2) {
System.out.println(msg+" "+i);
Thread.sleep(2000);
notify();
wait();
}
} else {
for(int i=1;i<=10;i+=2) {
System.out.println(msg+" "+i);
Thread.sleep(2000);
notify();
wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class PrintOdd extends Thread{
Printoddeven oddeven;
public PrintOdd(Printoddeven oddeven){
this.oddeven=oddeven;
}
public void run(){
oddeven.print("ODD");
}
}
class PrintEven extends Thread{
Printoddeven oddeven;
public PrintEven(Printoddeven oddeven){
this.oddeven=oddeven;
}
public void run(){
oddeven.print("Even");
}
}
public class mainclass
{
public static void main(String[] args) {
Printoddeven obj = new Printoddeven();//only one object
PrintEven t1=new PrintEven(obj);
PrintOdd t2=new PrintOdd(obj);
t1.start();
t2.start();
}
}
Ответ 14
Это мое решение проблемы. У меня есть два класса, реализующих Runnable
, один печатает нечетную последовательность, а другой печатает четную. У меня есть экземпляр Object
, который я использую для блокировки. Я инициализирую два класса одним и тем же объектом. Существует synchronized block
внутри метода run двух классов, где внутри цикла каждый метод печатает одно из чисел, уведомляет другой поток, ожидая блокировки на том же объекте, а затем сам ожидает той же блокировки снова.
Классы:
public class PrintEven implements Runnable{
private Object lock;
public PrintEven(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
for (int i = 2; i <= 10; i+=2) {
System.out.println("EVEN:="+i);
lock.notify();
try {
//if(i!=10) lock.wait();
lock.wait(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintOdd implements Runnable {
private Object lock;
public PrintOdd(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
for (int i = 1; i <= 10; i+=2) {
System.out.println("ODD:="+i);
lock.notify();
try {
//if(i!=9) lock.wait();
lock.wait(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintEvenOdd {
public static void main(String[] args){
Object lock = new Object();
Thread thread1 = new Thread(new PrintOdd(lock));
Thread thread2 = new Thread(new PrintEven(lock));
thread1.start();
thread2.start();
}
}
В моем примере верхний предел равен 10. Как только нечетный поток печатает 9 или четный поток печатает 10, нам больше не нужны никакие потоки для ожидания. Таким образом, мы можем справиться с этим, используя один if-block
. Или мы можем использовать перегруженный метод wait(long timeout)
для ожидания ожидания. Здесь есть один недостаток. С помощью этого кода мы не можем гарантировать, какой поток начнет выполнение первым.
Другой пример, используя Lock and Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockConditionOddEven {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition evenCondition = lock.newCondition();
Condition oddCondition = lock.newCondition();
Thread evenThread = new Thread(new EvenPrinter(10, lock, evenCondition, oddCondition));
Thread oddThread = new Thread(new OddPrinter(10, lock, evenCondition, oddCondition));
oddThread.start();
evenThread.start();
}
static class OddPrinter implements Runnable{
int i = 1;
int limit;
Lock lock;
Condition evenCondition;
Condition oddCondition;
public OddPrinter(int limit) {
super();
this.limit = limit;
}
public OddPrinter(int limit, Lock lock, Condition evenCondition, Condition oddCondition) {
super();
this.limit = limit;
this.lock = lock;
this.evenCondition = evenCondition;
this.oddCondition = oddCondition;
}
@Override
public void run() {
while( i <=limit) {
lock.lock();
System.out.println("Odd:"+i);
evenCondition.signal();
i+=2;
try {
oddCondition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
static class EvenPrinter implements Runnable{
int i = 2;
int limit;
Lock lock;
Condition evenCondition;
Condition oddCondition;
public EvenPrinter(int limit) {
super();
this.limit = limit;
}
public EvenPrinter(int limit, Lock lock, Condition evenCondition, Condition oddCondition) {
super();
this.limit = limit;
this.lock = lock;
this.evenCondition = evenCondition;
this.oddCondition = oddCondition;
}
@Override
public void run() {
while( i <=limit) {
lock.lock();
System.out.println("Even:"+i);
i+=2;
oddCondition.signal();
try {
evenCondition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
}
}
Ответ 15
Вот рабочий код для печати нечетных, даже не используя механизм ожидания и уведомления. Я ограничиваю предел чисел для печати от 1 до 50.
public class NotifyTest {
Object ob=new Object();
public static void main(String[] args) {
// TODO Auto-generated method stub
NotifyTest nt=new NotifyTest();
even e=new even(nt.ob);
odd o=new odd(nt.ob);
Thread t1=new Thread(e);
Thread t2=new Thread(o);
t1.start();
t2.start();
}
}
class even implements Runnable
{
Object lock;
int i=2;
public even(Object ob)
{
this.lock=ob;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(i<=50)
{
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Even Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i);
i=i+2;
}
}
}
class odd implements Runnable
{
Object lock;
int i=1;
public odd(Object ob)
{
this.lock=ob;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(i<=49)
{
synchronized (lock) {
System.out.println("Odd Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i);
i=i+2;
lock.notify();
}
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Ответ 16
Ниже приводится моя реализация с использованием 2 Семафоров.
- Нечетный семафор с разрешением 1.
- Даже Семафор с разрешением 0.
- Передайте два Семафора в оба потока как следующую подпись (мой, другой): -
- В Нечетный поток проходит в порядке (нечетно, четно)
- To Even thread pass в этом порядке (четный, нечетный)
- run() логика метода - my.acquireUninterruptibly() → Print → other.release()
- В потоке Even, поскольку даже Sema равен 0, он будет блокироваться.
- В нечетном потоке, когда нечетная Sema доступна (от init до 1), это будет печатать 1, а затем освобождать даже Sema, позволяя запустить Even thread.
-
Даже поток запускает отпечатки 2 и освобождает нечетную Sema, позволяющую работать с нечетным потоком.
import java.util.concurrent.Semaphore;
public class EvenOdd {
private final static String ODD = "ODD";
private final static String EVEN = "EVEN";
private final static int MAX_ITERATIONS = 10;
public static class EvenOddThread implements Runnable {
private String mType;
private int mNum;
private Semaphore mMySema;
private Semaphore mOtherSema;
public EvenOddThread(String str, Semaphore mine, Semaphore other) {
mType = str;
mMySema = mine;//new Semaphore(1); // start out as unlocked
mOtherSema = other;//new Semaphore(0);
if(str.equals(ODD)) {
mNum = 1;
}
else {
mNum = 2;
}
}
@Override
public void run() {
for (int i = 0; i < MAX_ITERATIONS; i++) {
mMySema.acquireUninterruptibly();
if (mType.equals(ODD)) {
System.out.println("Odd Thread - " + mNum);
} else {
System.out.println("Even Thread - " + mNum);
}
mNum += 2;
mOtherSema.release();
}
}
}
public static void main(String[] args) throws InterruptedException {
Semaphore odd = new Semaphore(1);
Semaphore even = new Semaphore(0);
System.out.println("Start!!!");
System.out.println();
Thread tOdd = new Thread(new EvenOddThread(ODD,
odd,
even));
Thread tEven = new Thread(new EvenOddThread(EVEN,
even,
odd));
tOdd.start();
tEven.start();
tOdd.join();
tEven.join();
System.out.println();
System.out.println("Done!!!");
}
}
Ниже приведен вывод: -
Start!!!
Odd Thread - 1
Even Thread - 2
Odd Thread - 3
Even Thread - 4
Odd Thread - 5
Even Thread - 6
Odd Thread - 7
Even Thread - 8
Odd Thread - 9
Even Thread - 10
Odd Thread - 11
Even Thread - 12
Odd Thread - 13
Even Thread - 14
Odd Thread - 15
Even Thread - 16
Odd Thread - 17
Even Thread - 18
Odd Thread - 19
Even Thread - 20
Done!!!
Ответ 17
Я думаю, что предоставляемые решения излишне добавили материал и не используют семафоры в полном объеме. Здесь мое решение.
package com.test.threads;
import java.util.concurrent.Semaphore;
public class EvenOddThreadTest {
public static int MAX = 100;
public static Integer number = new Integer(0);
//Unlocked state
public Semaphore semaphore = new Semaphore(1);
class PrinterThread extends Thread {
int start = 0;
String name;
PrinterThread(String name ,int start) {
this.start = start;
this.name = name;
}
@Override
public void run() {
try{
while(start < MAX){
// try to acquire the number of semaphore equal to your value
// and if you do not get it then wait for it.
semaphore.acquire(start);
System.out.println(name + " : " + start);
// prepare for the next iteration.
start+=2;
// release one less than what you need to print in the next iteration.
// This will release the other thread which is waiting to print the next number.
semaphore.release(start-1);
}
} catch(InterruptedException e){
}
}
}
public static void main(String args[]) {
EvenOddThreadTest test = new EvenOddThreadTest();
PrinterThread a = test.new PrinterThread("Even",1);
PrinterThread b = test.new PrinterThread("Odd", 2);
try {
a.start();
b.start();
} catch (Exception e) {
}
}
}
Ответ 18
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();
}
}
Ответ 19
Рабочее решение с использованием одного класса
package com.fursa.threads;
public class PrintNumbers extends Thread {
Object lock;
PrintNumbers(Object lock) {
this.lock = lock;
}
public static void main(String ar[]) {
Object obj = new Object();
// This constructor is required for the identification of wait/notify
// communication
PrintNumbers odd = new PrintNumbers(obj);
PrintNumbers even = new PrintNumbers(obj);
odd.setName("Odd");
even.setName("Even");
even.start();
odd.start();
}
@Override
public void run() {
for(int i=0;i<=100;i++) {
synchronized (lock) {
if (Thread.currentThread().getName().equals("Even")) {
if(i % 2 == 0 ){
System.out.println(Thread.currentThread().getName() + " - "+ i);
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if (i % 2 != 0 ) {
lock.notify();
}
}
if (Thread.currentThread().getName().equals("Odd")) {
if(i % 2 == 1 ){
System.out.println(Thread.currentThread().getName() + " - "+ i);
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else if (i % 2 != 1 ) {
lock.notify();
}
}
}
}
}
}
Ответ 20
Вы можете использовать следующий код, чтобы получить результат с созданием двух анонимных классов потоков.
package practice;
class Display {
boolean isEven = false;
synchronized public void printEven(int number) throws InterruptedException {
while (isEven)
wait();
System.out.println("Even : " + number);
isEven = true;
notify();
}
synchronized public void printOdd(int number) throws InterruptedException {
while (!isEven)
wait();
System.out.println("Odd : " + number);
isEven = false;
notify();
}
}
public class OddEven {
public static void main(String[] args) {
// TODO Auto-generated method stub
final Display disp = new Display();
new Thread() {
public void run() {
int num = 0;
for (int i = num; i <= 10; i += 2) {
try {
disp.printEven(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
int num = 1;
for (int i = num; i <= 10; i += 2) {
try {
disp.printOdd(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
Ответ 21
Это может быть достигнуто с помощью Lock и Condition:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class EvenOddThreads {
public static void main(String[] args) throws InterruptedException {
Printer p = new Printer();
Thread oddThread = new Thread(new PrintThread(p,false),"Odd :");
Thread evenThread = new Thread(new PrintThread(p,true),"Even :");
oddThread.start();
evenThread.start();
}
}
class PrintThread implements Runnable{
Printer p;
boolean isEven = false;
PrintThread(Printer p, boolean isEven){
this.p = p;
this.isEven = isEven;
}
@Override
public void run() {
int i = (isEven==true) ? 2 : 1;
while(i < 10 ){
if(isEven){
p.printEven(i);
}else{
p.printOdd(i);
}
i=i+2;
}
}
}
class Printer{
boolean isEven = true;
Lock lock = new ReentrantLock();
Condition condEven = lock.newCondition();
Condition condOdd = lock.newCondition();
public void printEven(int no){
lock.lock();
while(isEven==true){
try {
condEven.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() +no);
isEven = true;
condOdd.signalAll();
lock.unlock();
}
public void printOdd(int no){
lock.lock();
while(isEven==false){
try {
condOdd.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() +no);
isEven = false;
condEven.signalAll();
lock.unlock();
}
}
Ответ 22
Класс для печати нечетных Четное число
public class PrintOddEven implements Runnable {
private int max;
private int number;
public PrintOddEven(int max_number,int number) {
max = max_number;
this.number = number;
}
@Override
public void run() {
while(number<=max)
{
if(Thread.currentThread().getName().equalsIgnoreCase("odd"))
{
try {
printOdd();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
try {
printEven();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public synchronized void printOdd() throws InterruptedException
{
if(number%2==0)
{
wait();
}
System.out.println(number+Thread.currentThread().getName());
number++;
notifyAll();
}
public synchronized void printEven() throws InterruptedException
{
if(number%2!=0)
{
wait();
}
System.out.println(number+Thread.currentThread().getName());
number++;
notifyAll();
}
}
Программа драйверов
public class OddEvenThread {
public static void main(String[] args) {
PrintOddEven printer = new PrintOddEven(10,1);
Thread thread1 = new Thread(printer,"odd");
Thread thread2 = new Thread (printer,"even");
thread1.start();
thread2.start();
}
}
Ответ 23
public class Solution {
static class NumberGenerator{
private static volatile boolean printEvenNumber = false;
public void printEvenNumber(int i) {
synchronized (this) {
if(!printEvenNumber) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
printEvenNumber = !printEvenNumber;
notify();
}
}
public void printOddNumber(int i ) {
synchronized (this) {
if(printEvenNumber) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
printEvenNumber = !printEvenNumber;
notify();
}
}
}
static class OddNumberGenerator implements Runnable{
private NumberGenerator numberGenerator;
public OddNumberGenerator(NumberGenerator numberGenerator) {
this.numberGenerator = numberGenerator;
}
@Override
public void run() {
for(int i = 1; i <100; i = i + 2) {
numberGenerator.printOddNumber(i);
}
}
}
static class EvenNumberGenerator implements Runnable {
private NumberGenerator numberGenerator;
public EvenNumberGenerator(NumberGenerator numberGenerator) {
this.numberGenerator = numberGenerator;
}
@Override
public void run() {
for (int i = 2; i <= 100; i = i + 2) {
numberGenerator.printEvenNumber(i);
}
}
}
public static void main(String[] args) {
NumberGenerator ng = new NumberGenerator();
OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(ng);
EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(ng);
new Thread(oddNumberGenerator).start();
new Thread(evenNumberGenerator).start();
}
}
Ответ 24
public class ThreadEvenOdd {
static int cnt=0;
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized(this) {
while(cnt<101) {
if(cnt%2==0) {
System.out.print(cnt+" ");
cnt++;
}
notifyAll();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized(this) {
while(cnt<101) {
if(cnt%2==1) {
System.out.print(cnt+" ");
cnt++;
}
notifyAll();
}
}
}
});
t1.start();
t2.start();
}
}
Ответ 25
public class OddAndEvenThreadProblems {
private static Integer i = 0;
public static void main(String[] args) {
new EvenClass().start();
new OddClass().start();
}
public static class EvenClass extends Thread {
public void run() {
while (i < 10) {
synchronized (i) {
if (i % 2 == 0 ) {
try {
Thread.sleep(1000);
System.out.println(" EvenClass " + i);
i = i + 1;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
public static class OddClass extends Thread {
@Override
public void run() {
while (i < 10) {
synchronized (i) {
if (i % 2 == 1) {
try {
Thread.sleep(1000);
System.out.println(" OddClass " + i);
i = i + 1;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
}
OUTPUT will be :-
EvenClass 0
OddClass 1
EvenClass 2
OddClass 3
EvenClass 4
OddClass 5
EvenClass 6
OddClass 7
EvenClass 8
OddClass 9
Ответ 26
package programs.multithreading;
public class PrintOddEvenNoInSequence {
final int upto;
final PrintOddEvenNoInSequence obj;
volatile boolean oddFlag,evenFlag;
public PrintOddEvenNoInSequence(int upto){
this.upto = upto;
obj = this;
oddFlag = true;
evenFlag = false;
}
void printInSequence(){
Thread odd = new Thread(new Runnable() {
@Override
public void run() {
for(int i = 1; i <= upto; i = i + 2){
synchronized (obj) {
while(!oddFlag){
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Odd:"+i);
oddFlag = false;
evenFlag = true;
obj.notify();
}
}
}
});
Thread even = new Thread(new Runnable() {
@Override
public void run() {
for(int i = 2; i <= upto; i = i + 2){
synchronized (obj) {
while(!evenFlag){
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Even:"+i);
oddFlag = true;
evenFlag = false;
obj.notify();
}
}
}
});
odd.start();
even.start();
}
public static void main(String[] args) {
new PrintOddEvenNoInSequence(100).printInSequence();
}
}
Ответ 27
package example;
public class PrintSeqTwoThreads {
public static void main(String[] args) {
final Object mutex = new Object();
Thread t1 = new Thread() {
@Override
public void run() {
for (int j = 0; j < 10;) {
synchronized (mutex) {
System.out.println(Thread.currentThread().getName() + " " + j);
j = j + 2;
mutex.notify();
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
for (int j = 1; j < 10;) {
synchronized (mutex) {
System.out.println(Thread.currentThread().getName() + " " + j);
j = j + 2;
mutex.notify();
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
t1.start();
t2.start();
}
}
Ответ 28
Пожалуйста, используйте следующий код для печати нечетного и четного числа в правильном порядке вместе с желаемыми сообщениями.
package practice;
class Test {
private static boolean oddFlag = true;
int count = 1;
private void oddPrinter() {
synchronized (this) {
while(true) {
try {
if(count < 10) {
if(oddFlag) {
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ": " + count++);
oddFlag = !oddFlag;
notifyAll();
}
else {
wait();
}
}
else {
System.out.println("Odd Thread finished");
notify();
break;
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void evenPrinter() {
synchronized (this) {
while (true) {
try {
if(count < 10) {
if(!oddFlag) {
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ": " + count++);
oddFlag = !oddFlag;
notify();
}
else {
wait();
}
}
else {
System.out.println("Even Thread finished");
notify();
break;
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException{
final Test test = new Test();
Thread t1 = new Thread(new Runnable() {
public void run() {
test.oddPrinter();
}
}, "Thread 1");
Thread t2 = new Thread(new Runnable() {
public void run() {
test.evenPrinter();
}
}, "Thread 2");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Main thread finished");
}
}
Ответ 29
Я не мог понять большинство кодов, которые были здесь, поэтому я написал сам, возможно, это помогает кому-то вроде меня:
ПРИМЕЧАНИЕ. Это не использует отдельный режим печати и нечетный. Один метод print() делает все это.
public class test {
private static int START_INT = 1;
private static int STOP_INT = 10;
private static String THREAD_1 = "Thread A";
private static String THREAD_2 = "Thread B";
public static void main(String[] args) {
SynchronizedRepository syncRep = new SynchronizedRepository(START_INT,STOP_INT);
Runnable r1 = new EvenOddWorker(THREAD_1,syncRep);
Runnable r2 = new EvenOddWorker(THREAD_2,syncRep);
Thread t1 = new Thread(r1, THREAD_1);
Thread t2 = new Thread(r2, THREAD_2);
t1.start();
t2.start();
}
}
public class SynchronizedRepository {
private volatile int number;
private volatile boolean isSlotEven;
private int startNumber;
private int stopNumber;
public SynchronizedRepository(int startNumber, int stopNumber) {
super();
this.number = startNumber;
this.isSlotEven = startNumber%2==0;
this.startNumber = startNumber;
this.stopNumber = stopNumber;
}
public synchronized void print(String threadName) {
try {
for(int i=startNumber; i<=stopNumber/2; i++){
if ((isSlotEven && number % 2 == 0)||
(!isSlotEven && number % 2 != 0)){
System.out.println(threadName + " "+ number);
isSlotEven = !isSlotEven;
number++;
}
notifyAll();
wait();
}
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class EvenOddWorker implements Runnable {
private String threadName;
private SynchronizedRepository syncRep;
public EvenOddWorker(String threadName, SynchronizedRepository syncRep) {
super();
this.threadName = threadName;
this.syncRep = syncRep;
}
@Override
public void run() {
syncRep.print(threadName);
}
}
Ответ 30
Простое решение:)
package com.code.threads;
public class PrintOddEven extends Thread {
private Object lock;
static volatile int count = 1;
PrintOddEven(Object lock) {
this.lock = lock;
}
@Override
public void run () {
while(count <= 10) {
if (count % 2 == 0) {
synchronized(lock){
System.out.println("Even - " + count);
++count;
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
synchronized(lock){
System.out.println("Odd - " + count);
++count;
lock.notify();
}
}
}
}
public static void main(String[] args) {
Object obj = new Object();
PrintOddEven even = new PrintOddEven(obj);
PrintOddEven odd = new PrintOddEven(obj);
even.start();
odd.start();
}
}