# a simpler way of writing

There are three things in this world that no one can take away: one is the food in the stomach, the other is the dream hidden in the heart, and the third is the book that is read into the brain

• Analyze the topic. Two threads need to be used to alternately print odd and even numbers.
• Use synchronization locks to solve this problem
• Use semaphores to achieve alternate printing
• Define two semaphores, one odd semaphore and one even semaphore, both initialized to 1
• Use the even numbered semaphore first, because the odd number should be started first, and then released after the odd number is printed

# Semaphore implementation

• Specific implementation ideas:
• Define two semaphores, one odd semaphore and one even semaphore, both initialized to 1
• Use the even numbered semaphore first, because the odd number should be started first, and then released after the odd number is printed
• The specific process is to subtract even-numbered semaphores for the first time, and use odd-numbered semaphores after odd-numbered threads are printed. Then release the even number of semaphores and cycle like this
```import java.util.concurrent.Semaphore;

/**
* @ClassName AlternatePrinting
* @Author yunlogn
* @Date 2019/5/21
* @Description Print odd and even numbers alternately
*/
public class AlternatePrinting {

static int i = 0;
public static void main(String[] args) throws InterruptedException {

Semaphore semaphoreOdd = new Semaphore(1);
Semaphore semaphoreEven = new Semaphore(1);

semaphoreOdd.acquire();  //Let the odd number wait for the start first, so first subtract the even numbered semaphore and wait for the odd numbered thread to release

SemaphorePrintEven semaphorePrintEven = new SemaphorePrintEven(semaphoreOdd, semaphoreEven);
t1.start();

SemaphorePrintOdd semaphorePrintOdd = new SemaphorePrintOdd(semaphoreOdd, semaphoreEven);
t2.start();

}

/**
* Implemented using semaphores
*/
static class SemaphorePrintOdd implements Runnable {

private Semaphore semaphoreOdd;
private Semaphore semaphoreEven;

public SemaphorePrintOdd(Semaphore semaphoreOdd, Semaphore semaphoreEven) {
this.semaphoreOdd = semaphoreOdd;
this.semaphoreEven = semaphoreEven;
}

@Override
public void run() {
try {

semaphoreOdd.acquire();//Obtain the semaphore semaphoreOdd was acquired the semaphore during initialization, so it is blocked here, so the following odd-numbered threads will be executed first
while (true) {
i++;
if (i % 2 == 0) {
semaphoreEven.release();//Release the even-numbered semaphore to unblock the odd-numbered thread
//Apply again to obtain the even-numbered semaphore, because it has been obtained before, if there is no odd-numbered thread to release, then it will always be blocked here, waiting for the odd-numbered thread to release
semaphoreOdd.acquire();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

static class SemaphorePrintEven implements Runnable {

private Semaphore semaphoreOdd;
private Semaphore semaphoreEven;

public SemaphorePrintEven(Semaphore semaphoreOdd, Semaphore semaphoreEven) {
this.semaphoreOdd = semaphoreOdd;
this.semaphoreEven = semaphoreEven;
}

@Override
public void run() {

try {

semaphoreEven.acquire();
while (true) {
i++;
if (i % 2 == 1) {
semaphoreOdd.release(); //Release the odd semaphore to unblock the even thread

//Block here, waiting for the even thread to release the semaphore
//To apply for the odd semaphore again, you need to wait for the even thread to finish executing and then release the semaphore, otherwise it will block
semaphoreEven.acquire();
}
}

} catch (Exception ex) {}

}
}
}```
copy
• It should be noted that if a thread is abnormally interrupted before it is released in time, it will cause another thread to wait all the time, resulting in a deadlock. Although this exception is not within the scope of this question, you can use finally to wrap and release lock resources

# genlock print

• Let two threads use the same lock. Alternately execute .
• Determine whether it is an odd number. If it is an odd number, enter the odd thread to print and add one. The thread then releases the lock resource. and then make the thread wait
• Determine whether it is an even number, if it is an even number, enter the even thread to print and add one. The thread then releases the lock resource. and then make the thread wait
```import java.util.concurrent.atomic.AtomicInteger;

/**
* @ClassName AlternatePrinting
* @Author yunlogn
* @Date 2019/5/21
* @Description Print odd and even numbers alternately
*/
public class AlternatePrinting {

public static AtomicInteger atomicInteger = new AtomicInteger(1);

public static void main(String[] args) throws InterruptedException {

a.start();
b.start();

}

public static class AThread implements Runnable {

@Override
public void run() {
while (true) {
synchronized (atomicInteger) {
if (atomicInteger.intValue() % 2 != 0) {
System.out.println("odd number of threads:" + atomicInteger.intValue());
atomicInteger.getAndIncrement();
// An odd number of threads releases the lock resource
atomicInteger.notify();
try {
atomicInteger.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
// odd number of threads waiting
atomicInteger.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}

public static class BThread implements Runnable {

@Override
public void run() {
while (true){
synchronized (atomicInteger){
if(atomicInteger.intValue() %2== 0 ){
atomicInteger.getAndIncrement();
// Even threads release lock resources
atomicInteger.notify();
try {
atomicInteger.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
atomicInteger.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}

}```
copy

## a simpler way of writing

```public class TheadTest {

public static void main(String[] args) {
print1.start();
print2.start();
}
}

class ShareData {
public static final AtomicInteger atomicInt = new AtomicInteger(0);
}

private Predicate<Integer> predicate;

public PrintDigitThread(Predicate<Integer> predicate, String name) {
this.predicate = predicate;
this.setName(name);
}

@Override
public void run() {
int v = ShareData.atomicInt.get();
while (v < 100) {
synchronized (ShareData.atomicInt) {
v = ShareData.atomicInt.get();
if (predicate.test(v)) {
ShareData.atomicInt.incrementAndGet();
try {
ShareData.atomicInt.notify();
} catch (Exception ex) {

}
} else {
try {
ShareData.atomicInt.wait();
} catch (Exception ex) {

}
}
}
}
}
}```
copy

Posted by webwannabee on Mon, 28 Nov 2022 20:17:12 +0530