解法1:使用Synchronized
package printNum;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SynchronizedExample {
private static int count = 2;
private static Object lock = new Object();
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
@Override
public void run() {
while (count <= 100) {
synchronized (lock){
System.out.println("偶: " + count);
//count++;
count--;
lock.notifyAll();
if(count<=100){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
executorService.execute(new Runnable() {
@Override
public void run() {
while (count <= 100) {
synchronized (lock){
System.out.println("奇: " + count);
count=count+3;
lock.notifyAll();
if(count<=100){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
});
}
}
解法2:使用ReentrantLock Condition 或者Semaphore
package printNum;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockCondition {
private static int count=2;
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition condition1= lock.newCondition();
private static final Condition condition2= lock.newCondition();
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
@Override
public void run() {
while (count<=100){
try {
lock.lock();
System.out.println("偶:"+count--);
condition1.await();
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
});
executorService.execute(new Runnable() {
@Override
public void run() {
while (count<=100){
try {
lock.lock();
System.out.println("奇:"+count);
count=count+3;
condition1.signal();
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
});
executorService.shutdown();
}
}
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
static int num = 2;
public static void main(String[] args) throws Exception{
final Semaphore oddSemaphore = new Semaphore(1);
final Semaphore evenSemaphore = new Semaphore(0);
// new Thread(new DigitPrinter(i,oddSemaphore,evenSemaphore)).start();
// new Thread(new DigitPrinter(i,evenSemaphore,oddSemaphore)).start();
new Thread(new Runnable() {
@Override
public void run() {
while (num <= 100){
try {
oddSemaphore.acquire();
System.out.println(num);
num=num-1;
evenSemaphore.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (num <= 100){
try {
evenSemaphore.acquire();
System.out.println(num);
num=num+3;
oddSemaphore.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}
class DigitPrinter implements Runnable{
static int num;
Semaphore curSemaphore;
Semaphore nextSemaphore;
public DigitPrinter(int num, Semaphore curSemaphore,Semaphore nextSemaphore) {
this.num = num;
this.curSemaphore = curSemaphore;
this.nextSemaphore = nextSemaphore;
}
@Override
public void run() {
while (num <= 100){
try {
curSemaphore.acquire();
System.out.println(num);
++num;
nextSemaphore.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}