评测题目2:两个线程交叉打印100以内奇偶数,打印结束后线程正常结束。

题目描述:

两个线程交叉打印100以内奇偶数,打印结束后线程正常结束。

思路:

该题考察的是对线程锁的使用,多线程情况下如何控制各自的执行时间段。

思路一:使用标志位

  • 使用两个线程交替打印奇数偶数,可以用长度为[101]的数组,(数组0的位置不用,为了保证打印的数字和位置保持一致)
  • 先验证数组当前位置的前一个位置的标志位是不是为1,如果是1,则当前线程开始进行打印,在当前线程执行完打印之后,会将数组中的对应的标志位置为1,
  • 如果数组当前位置的前一个位置的标志位是0,则当前线程阻塞一定时间,进行等待。
package thread;

import java.util.concurrent.locks.LockSupport;

public class Thread01 {
    public static void main(String[] args) throws Exception {
        Thread01 main = new Thread01();
        main.run();
    }
    int[] array = new int[101];
    void run() throws Exception{
        new Thread(new PrintThread(1)).start();
        new Thread(new PrintThread(2)).start();
    }
    class PrintThread implements Runnable{
        int id;
        //有参构造函数
        public PrintThread(int id){
            this.id = id;
        }// //Runnable接口的run方法所界定的边界就可以看作是线程代码的边界
        public void run(){
            int num = id;
            if(id == 1){
                System.out.println("id" + id + "-" + num);
                array[num] =1;
                num+=2;
            }
            while (num <=100){
                //判断数组中前一个位置(num-1)是否为1,如果是1则直接打印,如果是0,则将当前线程阻塞指定时间
                while (array[num-1] == 0){
                    //Java中LockSupport.parkNanos与Sleep都可以使当前线程阻塞指定时间,那么除了是否抛出interrupt异常以外
                    LockSupport.parkNanos(10);
                }
                System.out.println("id" + id + "-" + num);
                array[num] = 1;
                num +=2;
            }
        }
    }
}

思路二:使用线程锁

这种方式就很简单了,直接使用Lock就可以。初始化线程时在线程中设置一个标识,0代表打印偶数,1代表打印奇数。
定义一个全局变量num代表要打印的数字,在线程中判断当前要打印的数字是不是和本线程一直,即奇数=奇数线程,偶数对应偶数线程,如果一直则打印,num++,同时唤醒另外的线程;否则进行等待。
 

package twoTest;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test14 {
    public static void main(String[] args) throws Exception {
        Test14 t = new Test14();
        t.run();

    }
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();//获取condition对象
    int num = 1;

    void run() throws Exception {
        new Thread(new PrintThread(0)).start();
        new Thread(new PrintThread(1)).start();
    }

    class PrintThread implements Runnable {

        int id;
        public PrintThread(int id) {
            this.id = id;
        }
        public void run() {
            while (num <= 100) {
                lock.lock();//获取锁,上锁
                try {
                    if (num % 2 == id) {
                        System.out.println("id " + id + " - " + num);
                        num ++;
                        condition.signalAll();//唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。
                    } else {
                        condition.await();//造成当前线程在接到信号或被中断之前一直处于等待状态。
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();//解锁
                }
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值