网易多线程笔试题目学习

题目:一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。

package my.thread.test;  

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

/**
 * 一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。
 *
 * @author Eric
 *
 */
public class ThreadCommunicationTest {  

    private final Lock lock = new ReentrantLock();  

    private final Condition conditionA = lock.newCondition();
    private final Condition conditionB = lock.newCondition();  

    private static char currentThread = ‘A‘;  

    public static void main(String[] args) {  

        ThreadCommunicationTest test = new ThreadCommunicationTest();  

        ExecutorService service = Executors.newCachedThreadPool();  

        service.execute(test.new RunnableA());
        service.execute(test.new RunnableB());  

        service.shutdown();  

    }  

    private class RunnableA implements Runnable {                 

        public void run() {
            for (int i = 1; i <= 52; i++) {
                lock.lock();  

                try {
                    while (currentThread != ‘A‘) {
                        try {
                            conditionA.await();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }  

                    System.out.println(i);
                    if (i % 2 == 0) {
                        currentThread = ‘B‘;
                        conditionB.signal();
                    }
                } finally {
                    lock.unlock();
                }
            }  

        }  

    }  

    private class RunnableB implements Runnable {  

        @Override
        public void run() {
            for (char c = ‘A‘; c <= ‘Z‘; c++) {
                lock.lock();
                try {
                    while (currentThread != ‘B‘) {
                        try {
                            conditionB.await();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }  

                    System.out.println(c);
                    currentThread = ‘A‘;
                    conditionA.signal();
                } finally {
                    lock.unlock();
                }
            }  

        }  

    }
}

上面的代码是网上找的,通过研究,学习了很多:

1.为什么是while而不是用if来判断条件,做了如下的实验

package test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。
 *
 * @author Eric
 *
 */
public class ThreadCommunicationTest {

    private final Lock lock = new ReentrantLock();

    private final Condition conditionA = lock.newCondition();
    private final Condition conditionB = lock.newCondition();

    private static char currentThread = ‘A‘;

    public static void main(String[] args) {

        ThreadCommunicationTest test = new ThreadCommunicationTest();

        ExecutorService service = Executors.newCachedThreadPool();

        RunnableA a = test.new RunnableA();
        service.execute(a);

        service.execute(a);

        RunnableB b = test.new RunnableB();
        service.execute(b);

        service.shutdown();

    }

    private class RunnableA implements Runnable {

        public void run() {
            for (int i = 1; i <= 100; i++) {
                lock.lock();

                try {
                    if (currentThread != ‘A‘) {
                        try {
                            conditionA.await();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    System.out.println(i + "线程名称" + Thread.currentThread().getName());
                    if (i % 2 == 0) {
                        currentThread = ‘B‘;
                        conditionB.signal();
                    }
                } finally {
                    lock.unlock();
                }
            }

        }

    }

    private class RunnableB implements Runnable {

        @Override
        public void run() {
            for (char c = ‘A‘; c <= ‘Z‘; c++) {
                lock.lock();
                try {
                    while (currentThread != ‘B‘) {
                        try {
                            conditionB.await();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    System.out.println(c + "线程名称" + Thread.currentThread().getName());
                    currentThread = ‘A‘;
                    conditionA.signalAll();
                } finally {
                    lock.unlock();
                }
            }
        }

    }
}

 开了两个线程用于执行任务A,并把判断条件改为if,则会出现如下的结果:

说明在currentThread = B的时候执行了任务A,因为当任务B调用signalAll的时候,将两个任务A线程都唤醒,假设此时任务A的一个线程输出了两个数并把currentThread条件设为了B,此时另一个任务A线程和任务B线程会同时竞争锁,如果任务A线程竞争锁成功,则会出现混乱的情况,所以要用while来进行判断

时间: 2024-08-10 19:09:18

网易多线程笔试题目学习的相关文章

网易前端笔试题目笔记

实现一个半径为100px的黑色圆形 什么是闭包,举例子说明 清楚浮动的三种方式,原理 前端性能优化的5种以上的方式,原理 对一个数组的所有元素去重,并求数组中的最大值 设计一个登录功能,设计逻辑,并解释 实现向服务器接口 /service/send 异步发送格式为 {name:"163", gender: "m"}的参数的功能 实现一个三列布局,左侧宽度150px, 右侧宽度150px, 中间宽度450px 和左侧距离20px,和右侧距离30px 未知大小的元素A,

算法学习 并查集(笔试题目:找同伙)

题目背景太长,记得不清楚,暂参考<啊哈算法>一书,根据笔试题目大意改编如下: 警察正要捉获某地区的犯罪团伙,由于强盗人数过大,想查清楚有几个团伙非常困难. 根据上级指示,需要首先尽快抓获强盗A所在的团伙,这需要掌握 1 所在团伙的人数.先有资料如下: 强盗1 和 强盗2 是同伙 强盗3 和 强盗4 是同伙 强盗2 和 强盗5 是同伙 强盗3 和 强盗2 是同伙 注意,强盗的同伙的同伙也是同伙,问  强盗1 的同伙(不包括1自己)有多少人? 该题形式化表示如下: 每个测试实例首先包括2个整数:N

秒杀多线程第一篇 多线程笔试面试题汇总 ZZ 【多线程】

http://blog.csdn.net/morewindows/article/details/7392749 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些其它IT公司如百度,阿里巴巴的笔试面试题目,因此具有很强的针对性.系列中不但会详细讲解多线程同步互斥的各种“招式”,而且会进一步的讲解多线程同步互斥的“内功心法”.有了“招式”和“内功心法”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多线程试题. ----------------------

秒杀多线程第一篇 多线程笔试面试题汇总

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些其它IT公司如百度,阿里巴巴的笔试面试题目,因此具有很强的针对性.系列中不但会详细讲解多线程同步互斥的各种“招式”,而且会进一步的讲解多线程同步互斥的“内功心法”.有了“招式”和“内功心法”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多线程试题. -------------------------------------华丽的分割线

GameLoft笔试题目 [Online Network Programmer Test]

gameloft 笔试题目是英文的,前面全部是理论的,最后两道是编程题目. 1 2 3 4 5 最后两道编程题目 其实还算简单: #include <stdio.h> #include <string.h> #include <iostream> std::string itoa(int number){ char nstr[15]; sprintf(nstr,"%d",number); return std::string(nstr); } usi

C++笔试题目大全(笔试宝典)(不断完善中)

1.new . delete . malloc . free 关系 delete 会调用对象的析构函数 , 和 new 对应 free 只会释放内存, new 调用构造函数. malloc 与 free 是 C++/C 语言的标准库函数, new/delete 是 C++ 的运算符.它们都可用于申请动态内存和释放内存.对于非内部数据类型的对象而言,光用 maloc/free 无法满足动态对象的要求.对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数.由于 malloc/free

多线程笔试面试概念问答

题目转自http://blog.csdn.net/morewindows/article/details/7392749 第一题:线程的基本概念.线程的基本状态及状态之间的关系? 线程,有时称为轻量级进程,是CPU使用的基本单元:它由线程ID.程序计数器.寄存器集合和堆栈组成.它与属于同一进程的其他线程共享其代码段.数据段和其他操作系统资源(如打开文件和信号). 线程有四种状态:新生状态.可运行状态.被阻塞状态.死亡状态.状态之间的转换如下图所示: 第二题:线程与进程的区别? 1. 线程是进程的

多线程笔试面试题汇总

第一篇    多线程笔试面试题汇总 本文转载于秒杀多线程系列,原博客地址:http://blog.csdn.net/morewindows/article/details/7392749 多线程在笔试面试中经常出现,下面列出一些公司的多线程笔试面试题.首先是一些概念性的问答题,这些是多线程的基础知识,经常出现在面试中的第一轮面试(我参加2011年腾讯研究院实习生招聘时就被问到了几个概念性题目).然后是一些选择题,这些一般在笔试时出现,虽然不是太难,但如果在选择题上花费大多时间无疑会对后面的编程题

2017 校招网上笔试题目

2017 校招网上笔试题目 做了一下某大厂的笔试的题目 1. 一个表, visit(cookie_id, area1, area2, date) 给出各种查询策略中, 哪一种最好,每一条SQL语句大同小异, 几乎看不出区别, 还有6,7个选项,同时字数很长.一般的SQL语句好像有根据查询的嵌套顺序来比较差异的,但是这道题反而没有.反正蒙了一个.没有数字可算,心里没有底,应该证明了SQL语法可能会很大地影响查询效率. 2. 给了几个条件,判断你的名次.又是球赛的问题,考查你的推理能力. 3. en