JAVA多线程代码题
...大约 3 分钟
JAVA多线程代码题
学习资料
1.写一个双线程轮流打印1-100
思路1:传统wait/notifyAll + 等待标记mark
class ThreadDemo1_01 {
static AtomicInteger count = new AtomicInteger(1); // 定义计数器
static Object lock = new Object(); // 定义对象锁
static int mark = 1; // 定义全局等待标记(1-线程A执行;2-线程B执行)
public static void main(String[] args) {
// 线程A定义
Thread ta = new Thread(() -> {
while (count.get() < 100) {
synchronized (lock) {
while (mark != 1) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("线程A执行" + count.getAndIncrement()); // 打印并执行自增操作
lock.notifyAll(); // 唤醒
mark = 2; // 切换等待标记
}
}
});
// 线程B定义
Thread tb = new Thread(() -> {
while (count.get() <= 100) {
synchronized (lock) {
while (mark != 2) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("线程B执行" + count.getAndIncrement()); // 线程B打印信息
lock.notifyAll(); // 唤醒
mark = 1; // 切换等待标记
}
}
});
// 启动线程
ta.start();
tb.start();
}
}
思路2:信号量Semaphore
class ThreadDemo1_02 {
static AtomicInteger count = new AtomicInteger(1); // 定义计数器
static Semaphore s1 = new Semaphore(1);
static Semaphore s2 = new Semaphore(0);
public static void main(String[] args) {
// 线程A定义
Thread ta = new Thread(() -> {
try{
while(count.get() < 100) {
s1.acquire();
System.out.println("线程A执行" + count.getAndIncrement());
s2.release();
}
}catch (Exception e){
e.printStackTrace();
}
});
// 线程B定义
Thread tb = new Thread(() -> {
try{
while(count.get() < 100) {
s2.acquire();
System.out.println("线程B执行" + count.getAndIncrement());
s1.release();
}
}catch (Exception e){
e.printStackTrace();
}
});
ta.start();
tb.start();
}
}
思路3:LockSupport
class ThreadDemo1_03 {
static AtomicInteger count = new AtomicInteger(1); // 定义计数器
static Thread[] threads = new Thread[2];
public static void main(String[] args) {
threads[0] = new Thread(()->{
while(count.get() < 100) {
System.out.println("线程A执行" + count.getAndIncrement());
LockSupport.unpark(threads[1]);
LockSupport.park();
}
});
threads[1] = new Thread(()->{
while(count.get() < 100) {
LockSupport.park();
System.out.println("线程B执行" + count.getAndIncrement());
LockSupport.unpark(threads[0]);
}
});
threads[0].start();
threads[1].start();
}
}
同题目:【2个线程,交替打印1-100的奇偶数】
其本质上是一样的概念,但此处需做额外的奇数、偶数判断(此处以思路2进行参考),对比思路2代码,其在内存嵌套中多加了个while判断,用于明确限定奇数、偶数
class ThreadDemo1_04 {
static AtomicInteger count = new AtomicInteger(1); // 定义计数器
static Semaphore s1 = new Semaphore(1);
static Semaphore s2 = new Semaphore(0);
public static void main(String[] args) {
// 线程A打印奇数
Thread ta = new Thread(() -> {
while (count.get() < 100) {
while (count.get() % 2 == 1) {
try {
s1.acquire();
System.out.println("[奇数]线程A执行" + count.getAndIncrement());
s2.release();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
});
// 线程B打印偶数
Thread tb = new Thread(() -> {
while (count.get() <= 100) {
while (count.get() % 2 == 0) {
try {
s2.acquire();
System.out.println("[偶数]线程B执行" + count.getAndIncrement());
s1.release();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
});
ta.start();
tb.start();
}
}
2.三个线程顺序打出1-100
3.多线程问题:线程A,B、C,分别打印1、2、3,顺序执行10次
4.计数累加怎么线程安全,可以怎么实现,100个线程,每个线程累加100次
5.线程交叉打印12A34B56C,多种实现方式(一个打印数字,一个打印字母)
6.两个线程交替打印ABCD..Z字母,一个大写一个小写
7.两个线程交替打印出a1b2c3.....z26
8.两个线程,一个打印abcd,一个打印1234,需求交替打印出a1b2c3d4a1b2c3d4; 打印10轮
9.假设有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?目前有500张票,同时有1~44个购票窗口,模拟购票流程,打印购票结果,比如:从1窗口购买1张
10.模仿购票系统,票,剩余499张票
11.有一批任务Tasks,现在我需要实现按批次执行,并且批次可以动态指定,例如[1,3,5,7]第一批执行,[11,13,15,17]第二批执行,…,最后没有指定的任务就最后一起执行掉。批次之间需要按顺序,前一批执行完了才执行下一批
Powered by Waline v3.1.3