面试题:常见的多线程实战手撕代码(顺序打印数字、字母)

问题一:

  一个多线程的问题,用三个线程,顺序打印字母A-Z,输出结果是1A 2B 3C 1D 2E…打印完毕最后输出一个Ok。

代码一:

public class forCharacter {
	private static char c = 'A';
    private static int i = 0;
	public static void main(String[] args) throws InterruptedException {
		Runnable r = new Runnable() {
			public void run() {
				int threadId = Integer.parseInt(Thread.currentThread().getName());
				while(i < 26){
					if(i % 3 == threadId - 1){
						System.out.println("线程id:" + threadId + " " + (char)c++);  
						i++;
						if(i == 26)
							System.out.println("哈哈,祝拿到offer!");
					}
					try{
						Thread.sleep(1000);
					}catch(InterruptedException e){
						e.printStackTrace();
					}
				}
			}
		};
		Thread t1 = new Thread(r, "1");
		Thread t2 = new Thread(r, "2");
		Thread t3 = new Thread(r, "3");
		t1.start();
		t2.start();
		t3.start();
	}
}

  但是代码一存在问题:这样写的话,可能会造成资源浪费,所以我们可以通过加锁进行限制,但是加锁后,因为sleep不会释放锁,会导致其他线程无法获得执行机会。因此需要配合wait和notifyAll。

代码二:

public class forCharacter {
	/*
	 * Description:一个多线程的问题,用三个线程,顺序打印字母A-Z,输出结果是1A 2B 3C 1D 2E...打印完毕最后输出一个Ok
	 * Author:ZhangRuirui 
	 * Date:2018/05/25 
	 * Email:zhangrrbugfree@163.com
	 */
	private static char c = 'A';// 必要的时候声明为volatile类型的
	private static int i = 0;

	public static void main(String[] args) throws InterruptedException {
		Runnable r = new Runnable() {
			public void run() {
				synchronized (this) {
					try {
						int threadId = Integer.parseInt(Thread.currentThread().getName());
						System.out.println("当前线程id:" + threadId + " ");
						while (i < 26) {
							if (i % 3 == threadId - 1) {
								System.out.println("线程id:" + threadId + " " + (char) c++);
								i++;
								if (i == 26)
									System.out.println("哈哈,祝拿到offer!");
								notifyAll();// 唤醒其他线程
							} else {
								wait();// 阻塞自己,释放锁
							}
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};

		Thread t1 = new Thread(r, "1");
		Thread t2 = new Thread(r, "2");
		Thread t3 = new Thread(r, "3");
		t1.start();
		t2.start();
		t3.start();
	}
}

输出:

当前线程id:1 
线程id:1 A
当前线程id:2 
线程id:2 B
当前线程id:3 
线程id:3 C
线程id:1 D
线程id:2 E
线程id:3 F
线程id:1 G
线程id:2 H
线程id:3 I
线程id:1 J
线程id:2 K
线程id:3 L
线程id:1 M
线程id:2 N
线程id:3 O
线程id:1 P
线程id:2 Q
线程id:3 R
线程id:1 S
线程id:2 T
线程id:3 U
线程id:1 V
线程id:2 W
线程id:3 X
线程id:1 Y
线程id:2 Z
哈哈,祝拿到offer!

问题二:(快手)

  一个多线程的问题,用五个线程,顺序打印数字1~无穷大,其中每5个数字为1组,如下:其中id代表线程的id

id   1   2   3   4   5
no   1   2   3   4   5
no   6   7   8   9   10
no   11  12  13  14  15
no   ..  ..  ..  ..  ..

代码:

public class forCharacter2 {

	/*
	 * Description:一个多线程的问题,用五个线程,顺序打印数字1~无穷大,其中每5个数字为1组 
	 * Author:ZhangRuirui
	 * Date:2018/05/25 
	 * Email:zhangrrbugfree@163.com
	 */
	private static volatile int orderNum = 1;// 必要的时候声明为volatile类型的

	public static void main(String[] args) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
				synchronized (this) {
					try {
						int threadId = Integer.parseInt(Thread.currentThread().getName());
						while (true) {
							if (orderNum % 5 == threadId || orderNum % 5 == 0) {
								if (orderNum % 5 == 0)
									System.out.println("threadid = " + 5 + " " + orderNum++);
								else
									System.out.println("threadid = " + threadId + " " + orderNum++);
								Thread.sleep(1000);// 为了执行效果看的更清楚
								notifyAll();
							} else {
								wait();
							}
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		Thread t1 = new Thread(r, "1");
		Thread t2 = new Thread(r, "2");
		Thread t3 = new Thread(r, "3");
		Thread t4 = new Thread(r, "4");
		Thread t5 = new Thread(r, "5");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
	}
}

输出:

threadid = 1 1
threadid = 2 2
threadid = 3 3
threadid = 4 4
threadid = 5 5
threadid = 1 6
threadid = 2 7
threadid = 3 8
threadid = 4 9
threadid = 5 10
threadid = 1 11
threadid = 2 12
threadid = 3 13
threadid = 4 14
threadid = 5 15
threadid = 1 16
threadid = 2 17
下面死循环不断输出

------至所有正在努力奋斗的程序猿们!加油!!
有码走遍天下 无码寸步难行
1024 - 梦想,永不止步!
爱编程 不爱Bug
爱加班 不爱黑眼圈
固执 但不偏执
疯狂 但不疯癫
生活里的菜鸟
工作中的大神
身怀宝藏,一心憧憬星辰大海
追求极致,目标始于高山之巅
一群怀揣好奇,梦想改变世界的孩子
一群追日逐浪,正在改变世界的极客
你们用最美的语言,诠释着科技的力量
你们用极速的创新,引领着时代的变迁

——乐于分享,共同进步,欢迎补充
——Any comments greatly appreciated
——诚心欢迎各位交流讨论!QQ:1138517609
——CSDN:https://blog.csdn.net/u011489043
——简书:https://www.jianshu.com/u/4968682d58d1
——GitHub:https://github.com/selfconzrr

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BugFree_张瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值