用Semaphore加锁方式
import java.util.concurrent.Semaphore;
public class PrintNumber {
//打印偶数
static Semaphore printEven = new Semaphore(1);
//打印奇数
static Semaphore printOdd = new Semaphore(0);
public static void main(String[] args) throws InterruptedException {
PrintEven p1 = new PrintEven();
PrintOdd p2 = new PrintOdd();
p1.start();
p2.start();
p1.join();
p2.join();
}
static class PrintEven extends Thread {
@Override
public void run() {
for (int i = 0; i <= 10; i += 2) {
try {
printEven.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread().getName() + " " + i);
printOdd.release();
}
}
}
static class PrintOdd extends Thread {
@Override
public void run() {
for (int i = 1; i <= 10; i += 2) {
try {
printOdd.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread().getName() + " " + i);
printEven.release();
}
}
}
}
\\output
Thread-0 0
Thread-1 1
Thread-0 2
Thread-1 3
Thread-0 4
Thread-1 5
Thread-0 6
Thread-1 7
Thread-0 8
Thread-1 9
Thread-0 10
用 Lock Condition方式
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintNumber1 {
static Lock lock = new ReentrantLock();
//打印奇数
static Condition printOdd = lock.newCondition();
//打印偶数
static Condition printEven = lock.newCondition();
//0的时候打印偶数,1的时候打印奇数
static int point = 0;
public static void main(String[] args) throws InterruptedException {
PrintNumber.PrintEven p1 = new PrintNumber.PrintEven();
PrintNumber.PrintOdd p2 = new PrintNumber.PrintOdd();
p1.start();
p2.start();
p1.join();
p2.join();
}
static class PrintEven extends Thread {
@Override
public void run() {
for (int i = 0; i <= 10; i += 2) {
lock.lock();
try {
while (point != 0) {
printEven.await();
}
System.out.println(currentThread().getName() + " " + i);
point = 1;
printOdd.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
static class PrintOdd extends Thread {
@Override
public void run() {
for (int i = 1; i <= 10; i += 2) {
lock.lock();
try {
while (point != 1) {
printOdd.await();
}
System.out.println(currentThread().getName() + " " + i);
point = 0;
printEven.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
用Synchronize
public class PrintNumber2 {
public static void main(String[] args){
MyTask task = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for(int i = 1; i < 10; i += 2 ){
task.prin(i);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < 10; i += 2 ){
task.prin(i);
}
}
});
t1.setName("线程1");
t2.setName("线程2");
t2.start();
t1.start();
}
}
class MyTask{
public synchronized void prin(int num){
try {
this.notify();
System.out.println("当前线程" + Thread.currentThread().getName() + " : " + num);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
AtomciInteger 无需用到锁
public class PrintNumber3 {
public static void main(String[] args){
AtomicInteger at = new AtomicInteger(0);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while(at.get() < 10){
if(at.get() % 2 == 0){
System.out.println("t1: "+at.get());
at.getAndIncrement();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while(at.get() < 10){
if(at.get() % 2 == 1){
System.out.println("t2: "+at.get());
at.getAndIncrement();
}
}
}
});
t1.setName("线程1");
t2.setName("线程2");
t2.start();
t1.start();
}
}