如何实现两个线程交替打印奇偶数

1,问题描述

如何实现两个线程交替打印1-100之内的奇偶数?

2,解决方案

首先进行问题分析,两个线程交替打印奇偶数,涉及到的是两个线程间的通信和协作问题。我们知道,java实现线程间通信的方式通常是加锁和唤醒,最常用的是synchronized、wait、notify这三者的组合。代码如下。

public class NumberTest {
    public static int number = 0;
    public static void main(String[] args) {
        Object object = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (number < 100) {
                    synchronized (object) {
                        if (number % 2 == 0) {
                            System.out.println(number++);
                            //打印完成后,调用notifyAll,唤醒其他线程。
                            object.notifyAll();
                        } else {
                            //不应该自己打印时,进行等待,避免空循环浪费CPU。
                            try {
                                object.wait();
                            } catch (Exception e) {


                            }
                        }
                    }


                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (number < 100) {
                    synchronized (object) {
                        if (number % 2 == 1) {
                            System.out.println(number++);
                            //打印完成后,调用notifyAll,唤醒其他线程。
                            object.notifyAll();
                        } else {
                            //不应该自己打印时,进行等待,避免空循环浪费CPU。
                            try {
                                object.wait();
                            } catch (Exception e) {


                            }
                        }
                    }


                }
            }
        });
        t1.start();
        t2.start();
        try {
            t1.join();
            t1.join();
        } catch (Exception e) {


        }
    }


    @Test
    public void test1() {


    }
}

总结一下synchronized、wait、notify的使用模板,如下。

        synchronized (lockObject){
            while(condition matched){
                doSomething();
                lockObject.notify();
            }
            lockObject.wait();
        }

除了使用synchronized关键字之外,也可以使用可重入锁ReentrantLock实现,我们知道,ReentrantLock可以创建Condition,它有await和signal方法,可以实现与wait和notify相似的功能。代码如下。

public class NumberTest {
    public static int number = 0;


    public static void main1(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition1 = reentrantLock.newCondition();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (number < 100) {
                    reentrantLock.lock();
                    if (number % 2 == 1) {
                        System.out.println(Thread.currentThread().getId() + " : " + number);
                        number++;
                        condition1.signal();
                    } else {
                        try {
                            condition1.await();
                        } catch (Exception e) {


                        }
                    }


                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (number < 100) {
                    reentrantLock.lock();
                    if (number % 2 == 0) {
                        System.out.println(Thread.currentThread().getId() + " : " + number);
                        number++;
                        condition1.signal();
                    } else {
                        try {
                            condition1.await();
                        } catch (Exception e) {


                        }
                    }


                }
            }
        });
        t1.start();
        t2.start();
        try {
            t1.join();
            t1.join();
        } catch (Exception e) {


        }
    }


    @Test
    public void test1() {


    }
}

 

你可能感兴趣的:(Java开发)