【题目1】假如火车站有100张火车票要卖,现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况。
package org.fas;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger ticket = new AtomicInteger(100);
List<TicketThread> ticketThreadList = new ArrayList<TicketThread>() {
private static final long serialVersionUID = -5685976271837354289L;
{
add(new TicketThread(null, ticket));
add(new TicketThread(null, ticket));
add(new TicketThread(null, ticket));
add(new TicketThread(null, ticket));
add(new TicketThread(null, ticket));
}
};
CountDownLatch countDownLatch = new CountDownLatch(ticketThreadList.size());
ticketThreadList.parallelStream()
.peek(ticketThread -> ticketThread.setCountDownLatch(countDownLatch))
.map(Thread::new)
.forEach(Thread::start);
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class TicketThread implements Runnable {
private CountDownLatch countDownLatch;
private AtomicInteger ticket;
@Override
public void run() {
while (ticket.get() > 0) {
System.out.println(Thread.currentThread().getName() + "卖出倒数第" + ticket.getAndDecrement() + "张票");
}
System.out.println("已售罄");
countDownLatch.countDown();
}
}
【题目2】编写两个线程,一个线程打印1~52的整数,另一个线程打印A~Z的字母,打印顺序为12A34B56C……5152Z,即按照整数和字母的顺序从小到大打印,并且每打印两个整数后打印一个字母,交替循环打印,直到打印到整数52和字母Z。
package org.fas;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args) {
Semaphore digit = new Semaphore(1);
Semaphore letter = new Semaphore(0);
new Thread(new DigitThread(digit, letter)).start();
new Thread(new LetterThread(digit, letter)).start();
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class DigitThread implements Runnable {
private Semaphore digit;
private Semaphore letter;
@Override
public void run() {
try {
for (int i = 1; i <= 52; i++) {
digit.acquire();
System.out.print(i++);
System.out.print(i);
letter.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class LetterThread implements Runnable {
private Semaphore digit;
private Semaphore letter;
@Override
public void run() {
try {
for (char c = 'A'; c <= 'Z'; c++) {
letter.acquire();
System.out.print(c);
digit.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
【题目3】设计4个线程,其中两个线程每次对j增加1,另外两个线程每次对j减少1。
package org.fas;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
AtomicInteger atomicInteger = new AtomicInteger(50);
for (int i = 1; i <= 2; i++) {
new Thread(new AdditionThread(cyclicBarrier, atomicInteger)).start();
new Thread(new SubtractionThread(cyclicBarrier, atomicInteger)).start();
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class AdditionThread implements Runnable {
private CyclicBarrier cyclicBarrier;
private AtomicInteger atomicInteger;
@Override
public void run() {
int i = atomicInteger.incrementAndGet();
System.out.println(i);
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class SubtractionThread implements Runnable {
private CyclicBarrier cyclicBarrier;
private AtomicInteger atomicInteger;
@Override
public void run() {
int i = atomicInteger.decrementAndGet();
System.out.println(i);
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
【题目4】编写多线程程序,模拟多个人通过一个山洞。这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒,有10个人同时准备通过此山洞,显示每次通过山洞人的姓名和顺序。
package org.fas;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args) {
Semaphore cave = new Semaphore(1);
List<PersonThread> personThreadList = new ArrayList<PersonThread>() {
private static final long serialVersionUID = -5685976271837354289L;
{
for (int i = 1; i <= 10; i++) {
add(new PersonThread(null, cave));
}
}
};
CountDownLatch countDownLatch = new CountDownLatch(personThreadList.size());
personThreadList.parallelStream()
.peek(personThread -> personThread.setCountDownLatch(countDownLatch))
.map(Thread::new)
.forEach(Thread::start);
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class PersonThread implements Runnable {
private CountDownLatch countDownLatch;
private Semaphore cave;
@Override
public void run() {
try {
cave.acquire();
System.out.println(Thread.currentThread().getName() + "准备通过山洞");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() + "已通过山洞");
cave.release();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
}