两个线程交替顺序打印出数字1-10

两个线程交替顺序打印出数字1-10

Scroll Down

用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();
    }
 
}

方法很多,理解为主。不单单是孔乙己 回字的四种写法。