├── .idea ├── $PROJECT_FILE$ ├── .gitignore ├── checkstyle-idea.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jarRepositories.xml ├── misc.xml ├── qaplug_profiles.xml └── vcs.xml ├── pom.xml ├── src └── main │ └── java │ ├── AlternateLetterPrinting.java │ ├── AlternatePrintDemo.java │ ├── AlternatePrinting.java │ ├── AlternatePrintingNumberLetter.java │ ├── AlternatePrintingThreeThreads.java │ ├── AtomicCounterDemo.java │ ├── CrossPrint.java │ ├── CrossPrintWithLock.java │ ├── SequentialPrinting.java │ ├── TaskRunner.java │ ├── ThreadExecutionOrderDemo.java │ ├── ThreadJoinDemo.java │ ├── ThreadPoolTrader.java │ └── TicketSystemDemo.java └── target └── classes ├── AlternateLetterPrinting.class ├── AlternatePrintDemo.class ├── AlternatePrinting.class ├── AlternatePrintingNumberLetter.class ├── AlternatePrintingThreeThreads.class ├── AtomicCounterDemo$1.class ├── AtomicCounterDemo.class ├── CrossPrint.class ├── CrossPrintWithLock.class ├── SequentialPrinting.class ├── TaskRunner.class ├── ThreadExecutionOrderDemo.class ├── ThreadJoinDemo$Task.class ├── ThreadJoinDemo.class ├── ThreadPoolTrader$Worker.class ├── ThreadPoolTrader.class ├── TicketSystemDemo$TicketSeller.class └── TicketSystemDemo.class /.idea/$PROJECT_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10.12.0 5 | JavaOnly 6 | true 7 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | -------------------------------------------------------------------------------- /.idea/qaplug_profiles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 465 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | juc-pratice 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 19 13 | 19 14 | UTF-8 15 | 16 | 17 | 18 | 19 | org.projectlombok 20 | lombok 21 | 1.18.10 22 | 23 | 24 | 25 | ch.qos.logback 26 | logback-classic 27 | 1.2.3 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/AlternateLetterPrinting.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 5 | */ 6 | 7 | public class AlternateLetterPrinting { 8 | private static final Object lock = new Object(); 9 | private static char currentLetter = 'A'; 10 | private static boolean printUpperCase = true; 11 | 12 | public static void main(String[] args) { 13 | Thread upperCasePrinter = new Thread(()-> printLetter(true)); 14 | Thread lowerCasePrinter = new Thread(()-> printLetter(false)); 15 | 16 | upperCasePrinter.start(); 17 | lowerCasePrinter.start(); 18 | } 19 | 20 | private static void printLetter(boolean isUpperCaseThread) { 21 | while (currentLetter <= 'Z'){ 22 | synchronized (lock){ 23 | while (printUpperCase != isUpperCaseThread) { 24 | try { 25 | lock.wait(); 26 | } catch (InterruptedException e) { 27 | throw new RuntimeException(e); 28 | } 29 | } 30 | if (currentLetter > 'Z') { 31 | break; 32 | } 33 | if (isUpperCaseThread) { 34 | System.out.print( currentLetter); 35 | } else { 36 | System.out.print(Character.toLowerCase( currentLetter)); 37 | } 38 | 39 | printUpperCase = !printUpperCase; 40 | currentLetter++; 41 | 42 | lock.notifyAll(); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/AlternatePrintDemo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 5 | */ 6 | 7 | public class AlternatePrintDemo { 8 | 9 | private static final Object lock = new Object(); 10 | /** 11 | * 0 表示打印字母,1 表示数字 12 | */ 13 | private static int state = 0; 14 | private static int round = 0; 15 | 16 | public static void main(String[] args) { 17 | Thread printLetters = new Thread(() ->{ 18 | for(int i = 0; i < 40;i++){ 19 | synchronized (lock){ 20 | while(state != 0){ 21 | try { 22 | lock.wait(); 23 | } catch (InterruptedException e) { 24 | throw new RuntimeException(e); 25 | } 26 | } 27 | 28 | if(round < 10){ 29 | char letter = (char)('a' + (i % 4)); 30 | System.out.print(letter); 31 | state = 1; 32 | lock.notifyAll(); 33 | } 34 | } 35 | } 36 | }); 37 | 38 | Thread printNumbers = new Thread(() ->{ 39 | for(int i = 0; i < 40 ;i++){ 40 | synchronized (lock){ 41 | while(state != 1){ 42 | try { 43 | lock.wait(); 44 | } catch (InterruptedException e) { 45 | throw new RuntimeException(e); 46 | } 47 | } 48 | 49 | if(round < 10){ 50 | int number = (i % 4 )+ 1; 51 | System.out.print(number); 52 | 53 | if( (i + 1) % 4 == 0){ 54 | round++; 55 | } 56 | 57 | state = 0; 58 | lock.notifyAll(); 59 | } 60 | } 61 | } 62 | }); 63 | 64 | printNumbers.start(); 65 | printLetters.start(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/AlternatePrinting.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 两个线程轮流打印 1~100 5 | */ 6 | 7 | public class AlternatePrinting { 8 | private int currentNumber = 1; 9 | private final Object lock = new Object(); 10 | 11 | public static void main(String[] args) { 12 | AlternatePrinting ap = new AlternatePrinting(); 13 | 14 | // 创建奇数打印线程 15 | Thread oddPrinter = new Thread(() -> { 16 | ap.printNumber(true); 17 | }); 18 | oddPrinter.start(); 19 | 20 | // 创建偶数打印线程 21 | Thread evenPrinter = new Thread(() -> { 22 | ap.printNumber(false); 23 | }); 24 | evenPrinter.start(); 25 | } 26 | 27 | /** 28 | * 根据 isOdd 标志打印奇数或者偶数 29 | * 30 | * @param flag true:奇数 false:偶数 31 | */ 32 | private void printNumber(boolean flag) { 33 | while (currentNumber <= 100) { 34 | synchronized (lock) { 35 | while ((flag && currentNumber % 2 == 0) || (!flag && currentNumber % 2 == 1)) { 36 | try { 37 | // 如果当前线程不应该打印,等待 38 | lock.wait(); 39 | } catch (InterruptedException e) { 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | 44 | if (currentNumber <= 100) { 45 | System.out.println("Thread " + (flag ? "Odd " : "Even") + ": " + currentNumber); 46 | currentNumber++; 47 | lock.notifyAll(); 48 | } 49 | } 50 | } 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/AlternatePrintingNumberLetter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 5 | */ 6 | 7 | public class AlternatePrintingNumberLetter { 8 | private static final Object lock = new Object(); 9 | /** 10 | * 用于计数,确认打印的字母和数字 11 | */ 12 | private static int count = 1; 13 | /** 14 | * 控制标记,用于控制是否打印数字 15 | */ 16 | private static boolean printNumber = false; 17 | 18 | public static void main(String[] args) { 19 | // 创建打印数字的线程 20 | Thread printNumberThread = new Thread(() ->{ 21 | while(count <= 26){ 22 | synchronized (lock){ 23 | while(!printNumber){ 24 | try { 25 | lock.wait(); 26 | } catch (InterruptedException e) { 27 | throw new RuntimeException(e); 28 | } 29 | } 30 | if(count <= 26){ 31 | System.out.print(count); 32 | count++; 33 | printNumber = false; 34 | lock.notifyAll(); 35 | } 36 | } 37 | } 38 | }); 39 | // 创建打印字母的线程 40 | Thread printLetterThread = new Thread(()->{ 41 | while(count <= 26){ 42 | synchronized (lock){ 43 | while(printNumber) { 44 | try { 45 | lock.wait(); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | if (count <= 26){ 51 | char letter = (char)('a' + count - 1); 52 | System.out.print(letter); 53 | printNumber = true; 54 | lock.notify(); 55 | } 56 | } 57 | } 58 | }); 59 | printNumberThread.start(); 60 | printLetterThread.start(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/AlternatePrintingThreeThreads.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 三个线程顺序打印 1-100 5 | */ 6 | 7 | public class AlternatePrintingThreeThreads { 8 | /** 9 | * 当前要打印的数字 10 | */ 11 | private int currentNumber = 1; 12 | /** 13 | * 用于同步的锁对象 14 | */ 15 | private final Object lock = new Object(); 16 | /** 17 | * 控制哪个线程应该打印的标识 0:3n ,1:3n + 1,2: 3n + 2 18 | */ 19 | private int turn = 0; 20 | 21 | public static void main(String[] args) { 22 | AlternatePrintingThreeThreads ap = new AlternatePrintingThreeThreads(); 23 | 24 | // 创建并启动三个线程 25 | Thread t1 = new Thread(() -> ap.printNumbers(0)); 26 | Thread t2 = new Thread(() -> ap.printNumbers(1)); 27 | Thread t3 = new Thread(() -> ap.printNumbers(2)); 28 | 29 | t1.start(); 30 | t2.start(); 31 | t3.start(); 32 | 33 | } 34 | 35 | /** 36 | * 根据 turn 的值打印对应范围的数字 37 | * 38 | * @param offset 0:3n 1:3n+1 2:3n+2 39 | */ 40 | private void printNumbers(int offset) { 41 | while (currentNumber <= 100) { 42 | synchronized (lock) { 43 | while ((turn % 3) != offset) { 44 | try { 45 | lock.wait(); 46 | } catch (InterruptedException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | if (currentNumber <= 100 && (currentNumber - 1) % 3 == offset) { 51 | System.out.println("Thread " + (offset + 1) + " printed: " + currentNumber); 52 | currentNumber++; 53 | turn = (turn + 1) % 3; 54 | lock.notifyAll(); 55 | } 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/AtomicCounterDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.ExecutorService; 2 | import java.util.concurrent.Executors; 3 | import java.util.concurrent.TimeUnit; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | /** 7 | * @author linqi 8 | * @version 1.0.0 9 | * @description 10 | */ 11 | 12 | public class AtomicCounterDemo { 13 | 14 | private static final AtomicInteger counter = new AtomicInteger(0); 15 | 16 | public static void main(String[] args) throws InterruptedException { 17 | // 创建100个线程来增加计数器的值 18 | ExecutorService executor = Executors.newFixedThreadPool(100); 19 | 20 | // 提交 100 个任务,每个任务执行 100 次累加 21 | for (int i = 0; i < 100; i++) { 22 | executor.submit(new Runnable() { 23 | 24 | @Override 25 | public void run() { 26 | for (int i = 0; i < 100; i++) { 27 | counter.incrementAndGet(); 28 | } 29 | } 30 | }); 31 | } 32 | 33 | // 关闭线程池 34 | executor.shutdown(); 35 | // 等待所有任务完成 36 | executor.awaitTermination(1, TimeUnit.HOURS); 37 | 38 | // 输出最终的值 39 | System.out.println("Final counter value: " + counter.get()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/CrossPrint.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 线程交替打印 12A34B56C 使用 wait() 和 notifyAll() 5 | */ 6 | 7 | public class CrossPrint { 8 | private static final Object lock = new Object(); 9 | private static boolean printNumber = true; 10 | 11 | public static void main(String[] args) { 12 | Thread printNumberThread = new Thread(() ->{ 13 | for(int i = 1; i <= 52; i=i+2){ 14 | synchronized (lock){ 15 | while(!printNumber){ 16 | try { 17 | lock.wait(); 18 | } catch (InterruptedException e) { 19 | throw new RuntimeException(e); 20 | } 21 | } 22 | System.out.print(i); 23 | System.out.print(i + 1); 24 | printNumber = false;// 打印切换标志 25 | lock.notifyAll();// 唤醒等待的线程 26 | } 27 | } 28 | }); 29 | 30 | Thread printLetterThread = new Thread(() ->{ 31 | for(char c = 'A'; c <= 'Z'; c++){ 32 | synchronized (lock){ 33 | while(printNumber){ 34 | try { 35 | lock.wait(); 36 | } catch (InterruptedException e) { 37 | throw new RuntimeException(e); 38 | } 39 | } 40 | System.out.print(c); 41 | printNumber = true;// 打印切换标志 42 | lock.notifyAll();// 唤醒等待的线程 43 | } 44 | } 45 | }); 46 | 47 | printLetterThread.start(); 48 | printNumberThread.start(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/CrossPrintWithLock.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.locks.Condition; 2 | import java.util.concurrent.locks.Lock; 3 | import java.util.concurrent.locks.ReentrantLock; 4 | 5 | /** 6 | * @author linqi 7 | * @version 1.0.0 8 | * @description 9 | */ 10 | 11 | public class CrossPrintWithLock { 12 | private static final Lock lock = new ReentrantLock(); 13 | private static final Condition printNumberCondition = lock.newCondition(); 14 | private static final Condition printLetterCondition = lock.newCondition(); 15 | private static boolean printNumber = true; 16 | 17 | public static void main(String[] args) { 18 | Thread printNumberThread = new Thread(() ->{ 19 | for(int i = 1; i <= 52; i=i+2){ 20 | synchronized (lock){ 21 | while(!printNumber){ 22 | try { 23 | lock.wait(); 24 | } catch (InterruptedException e) { 25 | throw new RuntimeException(e); 26 | } 27 | } 28 | System.out.print(i); 29 | System.out.print(i + 1); 30 | printNumber = false;// 打印切换标志 31 | lock.notifyAll();// 唤醒等待的线程 32 | } 33 | } 34 | }); 35 | 36 | Thread printLetterThread = new Thread(() ->{ 37 | for(char c = 'A'; c <= 'Z'; c++){ 38 | synchronized (lock){ 39 | while(printNumber){ 40 | try { 41 | lock.wait(); 42 | } catch (InterruptedException e) { 43 | throw new RuntimeException(e); 44 | } 45 | } 46 | System.out.print(c); 47 | printNumber = true;// 打印切换标志 48 | lock.notifyAll();// 唤醒等待的线程 49 | } 50 | } 51 | }); 52 | 53 | printLetterThread.start(); 54 | printNumberThread.start(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/SequentialPrinting.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author linqi 3 | * @version 1.0.0 4 | * @description 线程 A、B、C 分别打印 1,2,3 顺序执行 10 次 5 | */ 6 | 7 | public class SequentialPrinting { 8 | /** 9 | * 当前线程打印的次数 10 | */ 11 | private int count = 0; 12 | /** 13 | * 用于同步锁对象 14 | */ 15 | private final Object lock = new Object(); 16 | 17 | public static void main(String[] args) { 18 | SequentialPrinting printer = new SequentialPrinting(); 19 | 20 | // 创建并启动线程 21 | Thread tA = new Thread(() -> printer.printNumber(1), "A"); 22 | Thread tB = new Thread(() -> printer.printNumber(2), "B"); 23 | Thread tC = new Thread(() -> printer.printNumber(3), "C"); 24 | 25 | tA.start(); 26 | tB.start(); 27 | tC.start(); 28 | } 29 | 30 | private void printNumber(int numberToPrint) { 31 | for (int i = 0; i < 10; i++) { 32 | synchronized (lock) { 33 | while (count % 3 != numberToPrint - 1) { 34 | try { 35 | lock.wait(); 36 | } catch (InterruptedException e) { 37 | throw new RuntimeException(e); 38 | } 39 | } 40 | 41 | if (count < 30) { 42 | System.out.println("Thread " + Thread.currentThread().getName() + ": " + numberToPrint); 43 | count++; 44 | lock.notifyAll(); 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/TaskRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.util.concurrent.ExecutionException; 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.Future; 6 | 7 | /** 8 | * @author linqi 9 | * @version 1.0.0 10 | * @description 11 | */ 12 | 13 | public class TaskRunner { 14 | 15 | public static void main(String[] args) { 16 | // 假设创建了 100 个任务 17 | List tasks = TaskRunner.createTasks(); 18 | 19 | // 第一批和第二批执行的任务索引 20 | List batch1 = new ArrayList(Arrays.asList(1, 3, 5, 7)); 21 | List batch2 = new ArrayList(Arrays.asList(11, 13, 15, 17)); 22 | 23 | List> batchs = new ArrayList<>(); 24 | batchs.add(batch1); 25 | batchs.add(batch2); 26 | 27 | try { 28 | runTasksInBatches(tasks, batchs); 29 | System.out.println("====== 全部任务执行完成!======"); 30 | 31 | } catch (ExecutionException e) { 32 | throw new RuntimeException(e); 33 | } catch (InterruptedException e) { 34 | throw new RuntimeException(e); 35 | } 36 | } 37 | 38 | private static void runTasksInBatches(List tasks, List> batchs) throws ExecutionException, InterruptedException { 39 | // 使用固定大小的线程池 40 | ExecutorService executor = Executors.newFixedThreadPool(10); 41 | 42 | // 执行第一批任务 43 | List> futures = new ArrayList>(); 44 | Set allBatchTaskIndexs = new HashSet(); 45 | for (int i = 0; i < batchs.size(); i++) { 46 | System.out.println("====== 第 " + (i + 1) + " 批任务开始执行!======"); 47 | for (int index : batchs.get(i)) { 48 | Future future = (Future) executor.submit(tasks.get(index)); 49 | futures.add(future); 50 | allBatchTaskIndexs.add(index); 51 | } 52 | // 等待一批任务完成 53 | for (Future f : futures) { 54 | f.get(); 55 | } 56 | futures.clear(); 57 | System.out.println("====== 第 " + (i + 1) + " 批任务执行完成!======"); 58 | } 59 | 60 | // 执行剩下的任务 61 | System.out.println("====== 最后 1 批任务开始执行!======"); 62 | for (int i = 0; i < tasks.size(); i++) { 63 | if (!allBatchTaskIndexs.contains(i)) { 64 | executor.submit(tasks.get(i)); 65 | } 66 | } 67 | 68 | 69 | // 关闭线程池,并且等待所有任务执行 70 | executor.shutdown(); 71 | while (!executor.isTerminated()) { 72 | // 等待所有任务执行完毕 73 | } 74 | System.out.println("====== 最后 1 批任务执行完成!======"); 75 | } 76 | 77 | private static List createTasks() { 78 | List tasks = new ArrayList<>(); 79 | // 创建任务的逻辑 80 | for (int i = 0; i < 30; i++) { 81 | final int taskId = i; 82 | tasks.add(() -> { 83 | try { 84 | long startTime = System.currentTimeMillis(); 85 | Thread.sleep((long) (Math.random() * 1000)); 86 | long endTime = System.currentTimeMillis(); 87 | System.out.println("执行任务,任务 ID :" + taskId + ",耗时:" + (endTime - startTime) + "ms"); 88 | } catch (InterruptedException e) { 89 | throw new RuntimeException(e); 90 | } 91 | }); 92 | } 93 | return tasks; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/ThreadExecutionOrderDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.CountDownLatch; 2 | 3 | /** 4 | * @author linqi 5 | * @version 1.0.0 6 | * @description 7 | */ 8 | 9 | public class ThreadExecutionOrderDemo { 10 | private static CountDownLatch t1ToT2Latch = new CountDownLatch(1); 11 | private static CountDownLatch t2ToT3Latch = new CountDownLatch(1); 12 | 13 | public static void main(String[] args) throws InterruptedException { 14 | Thread t1 = new Thread(() -> { 15 | long startTime = System.currentTimeMillis(); 16 | System.out.println("T1 开始执行!"); 17 | try { 18 | Thread.sleep((long) (Math.random() * 1000)); 19 | } catch (InterruptedException e) { 20 | throw new RuntimeException(e); 21 | } 22 | long endTime = System.currentTimeMillis(); 23 | System.out.println("T1 执行时间:" + (endTime - startTime) + "ms"); 24 | System.out.println("T1 执行完毕!"); 25 | System.out.println("------------------------------------------------"); 26 | t1ToT2Latch.countDown(); 27 | }, "T1"); 28 | 29 | Thread t2 = new Thread(() -> { 30 | try{ 31 | t1ToT2Latch.await(); 32 | } catch (InterruptedException e) { 33 | throw new RuntimeException(e); 34 | } 35 | long startTime = System.currentTimeMillis(); 36 | System.out.println("T2 开始执行!"); 37 | try { 38 | Thread.sleep((long) (Math.random() * 1000)); 39 | } catch (InterruptedException e) { 40 | throw new RuntimeException(e); 41 | } 42 | long endTime = System.currentTimeMillis(); 43 | System.out.println("T2 执行时间:" + (endTime - startTime) + "ms"); 44 | System.out.println("T2 执行完毕!"); 45 | System.out.println("------------------------------------------------"); 46 | t2ToT3Latch.countDown(); 47 | }, "T2"); 48 | Thread t3 = new Thread(() -> { 49 | try{ 50 | t2ToT3Latch.await(); 51 | } catch (InterruptedException e) { 52 | throw new RuntimeException(e); 53 | } 54 | long startTime = System.currentTimeMillis(); 55 | System.out.println("T3 开始执行!"); 56 | try { 57 | Thread.sleep((long) (Math.random() * 1000)); 58 | } catch (InterruptedException e) { 59 | throw new RuntimeException(e); 60 | } 61 | long endTime = System.currentTimeMillis(); 62 | System.out.println("T3 执行时间:" + (endTime - startTime) + "ms"); 63 | System.out.println("T3 执行完毕!"); 64 | }, "T3"); 65 | 66 | t1.start(); 67 | t2.start(); 68 | t3.start(); 69 | 70 | t1.join(); 71 | t2.join(); 72 | t3.join(); 73 | 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/ThreadJoinDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | /** 4 | * @author linqi 5 | * @version 1.0.0 6 | * @description T2 在 T1 之后执行,T3 在 T2 之后执行 7 | */ 8 | 9 | public class ThreadJoinDemo { 10 | 11 | public static void main(String[] args) { 12 | Thread t1 = new Thread(new Task("T1"), "T1"); 13 | Thread t2 = new Thread(new Task("T2"), "T2"); 14 | Thread t3 = new Thread(new Task("T3"), "T3"); 15 | 16 | 17 | // 启动 t1 18 | t1.start(); 19 | try { 20 | t1.join(); 21 | t2.start(); 22 | t2.join(); 23 | t3.start(); 24 | t3.join(); 25 | } catch (InterruptedException e) { 26 | throw new RuntimeException(e); 27 | } 28 | } 29 | 30 | 31 | private static class Task implements Runnable { 32 | private String name; 33 | 34 | public Task(String name) { 35 | this.name = name; 36 | } 37 | 38 | @Override 39 | public void run() { 40 | long startTime = System.currentTimeMillis(); 41 | System.out.println(name + " 开始执行!"); 42 | try { 43 | Thread.sleep((long) (Math.random() * 1000)); 44 | } catch (InterruptedException e) { 45 | throw new RuntimeException(e); 46 | } 47 | System.out.println(name + " 执行完毕!"); 48 | long endTime = System.currentTimeMillis(); 49 | System.out.println(name + " 执行时间:" + (endTime - startTime) + "ms"); 50 | System.out.println("--------------------------------"); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/ThreadPoolTrader.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.concurrent.ArrayBlockingQueue; 3 | import java.util.concurrent.BlockingQueue; 4 | import java.util.concurrent.Executor; 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | 7 | /** 8 | * @author linqi 9 | * @version 1.0.0 10 | * @description 11 | */ 12 | 13 | public class ThreadPoolTrader implements Executor { 14 | 15 | private final AtomicInteger ctl = new AtomicInteger(0); 16 | 17 | private volatile int corePoolSize; 18 | private volatile int maximumPoolSize; 19 | 20 | private final BlockingQueue workQueue; 21 | 22 | public ThreadPoolTrader(int corePoolSize, int maximumPoolSize, BlockingQueue workQueue) { 23 | this.corePoolSize = corePoolSize; 24 | this.maximumPoolSize = maximumPoolSize; 25 | this.workQueue = workQueue; 26 | } 27 | 28 | @Override 29 | public void execute(Runnable command) { 30 | int c = ctl.get(); 31 | if (c < corePoolSize) { 32 | if (!addWorker(command)) { 33 | reject(); 34 | } 35 | return; 36 | } 37 | if (!workQueue.offer(command)) { 38 | if (!addWorker(command)) { 39 | reject(); 40 | } 41 | } 42 | } 43 | 44 | private boolean addWorker(Runnable firstTask) { 45 | if (ctl.get() >= maximumPoolSize) { 46 | return false; 47 | } 48 | 49 | Worker worker = new Worker(firstTask); 50 | worker.thread.start(); 51 | ctl.incrementAndGet(); 52 | return true; 53 | } 54 | 55 | private final class Worker implements Runnable { 56 | 57 | final Thread thread; 58 | Runnable firstTask; 59 | 60 | public Worker(Runnable firstTask) { 61 | this.thread = new Thread(this); 62 | this.firstTask = firstTask; 63 | } 64 | 65 | @Override 66 | public void run() { 67 | Runnable task = firstTask; 68 | try { 69 | while (task != null || (task = getTask()) != null) { 70 | task.run(); 71 | if (ctl.get() > maximumPoolSize) { 72 | break; 73 | } 74 | task = null; 75 | } 76 | } finally { 77 | ctl.decrementAndGet(); 78 | } 79 | } 80 | 81 | private Runnable getTask() { 82 | for (; ; ) { 83 | try { 84 | System.out.println("workQueue.size:" + workQueue.size()); 85 | return workQueue.take(); 86 | } catch (InterruptedException e) { 87 | e.printStackTrace(); 88 | } 89 | } 90 | } 91 | } 92 | 93 | private void reject() { 94 | throw new RuntimeException("Error!ctl.count:" + ctl.get() + " workQueue.size:" + workQueue.size()); 95 | } 96 | 97 | public static void main(String[] args) { 98 | ThreadPoolTrader threadPoolTrader = new ThreadPoolTrader(2, 2, new ArrayBlockingQueue(10)); 99 | 100 | for (int i = 0; i < 10; i++) { 101 | int finalI = i; 102 | threadPoolTrader.execute(() -> { 103 | try { 104 | Thread.sleep(1500); 105 | } catch (InterruptedException e) { 106 | e.printStackTrace(); 107 | } 108 | System.out.println("任务编号:" + finalI); 109 | }); 110 | } 111 | } 112 | 113 | } -------------------------------------------------------------------------------- /src/main/java/TicketSystemDemo.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | /** 4 | * @author linqi 5 | * @version 1.0.0 6 | * @description 购票系统 7 | */ 8 | 9 | public class TicketSystemDemo { 10 | /** 11 | * 总共票数 12 | */ 13 | private static final int TOTAL_TICKETS = 1000; 14 | /** 15 | * 剩余票数 16 | */ 17 | private static int remainingTICKETS = TOTAL_TICKETS; 18 | /** 19 | * 锁对象,用于同步 20 | */ 21 | private static final Object lock = new Object(); 22 | 23 | public static void main(String[] args) { 24 | // 创建线程,并且启动 25 | for (int i = 0; i < 10; i++) { 26 | new Thread(new TicketSeller(i)).start(); 27 | } 28 | 29 | } 30 | 31 | private static class TicketSeller implements Runnable { 32 | private int windowNumber; 33 | 34 | public TicketSeller(int windowNumber) { 35 | this.windowNumber = windowNumber; 36 | } 37 | 38 | @Override 39 | public void run() { 40 | while (true) { 41 | synchronized (lock) { 42 | if (remainingTICKETS > 0) { 43 | try { 44 | Thread.sleep(100); 45 | } catch (InterruptedException e) { 46 | e.printStackTrace(); 47 | } 48 | buyTicket(); 49 | } else { 50 | break; 51 | } 52 | // 模拟购票后的其他操作,增加随机性 53 | try { 54 | Thread.sleep((long) (Math.random() * 1000)); 55 | } catch (InterruptedException e) { 56 | throw new RuntimeException(e); 57 | } 58 | } 59 | } 60 | } 61 | 62 | 63 | private void buyTicket() { 64 | int number = new Random().nextInt(10); 65 | if(remainingTICKETS >= number && number > 0){ 66 | remainingTICKETS = remainingTICKETS - number; 67 | System.out.println("从窗口 G1000" + windowNumber + " 购买了 " + number + " 张票, 还剩 " + remainingTICKETS + " 张票"); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /target/classes/AlternateLetterPrinting.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AlternateLetterPrinting.class -------------------------------------------------------------------------------- /target/classes/AlternatePrintDemo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AlternatePrintDemo.class -------------------------------------------------------------------------------- /target/classes/AlternatePrinting.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AlternatePrinting.class -------------------------------------------------------------------------------- /target/classes/AlternatePrintingNumberLetter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AlternatePrintingNumberLetter.class -------------------------------------------------------------------------------- /target/classes/AlternatePrintingThreeThreads.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AlternatePrintingThreeThreads.class -------------------------------------------------------------------------------- /target/classes/AtomicCounterDemo$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AtomicCounterDemo$1.class -------------------------------------------------------------------------------- /target/classes/AtomicCounterDemo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/AtomicCounterDemo.class -------------------------------------------------------------------------------- /target/classes/CrossPrint.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/CrossPrint.class -------------------------------------------------------------------------------- /target/classes/CrossPrintWithLock.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/CrossPrintWithLock.class -------------------------------------------------------------------------------- /target/classes/SequentialPrinting.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/SequentialPrinting.class -------------------------------------------------------------------------------- /target/classes/TaskRunner.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/TaskRunner.class -------------------------------------------------------------------------------- /target/classes/ThreadExecutionOrderDemo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/ThreadExecutionOrderDemo.class -------------------------------------------------------------------------------- /target/classes/ThreadJoinDemo$Task.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/ThreadJoinDemo$Task.class -------------------------------------------------------------------------------- /target/classes/ThreadJoinDemo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/ThreadJoinDemo.class -------------------------------------------------------------------------------- /target/classes/ThreadPoolTrader$Worker.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/ThreadPoolTrader$Worker.class -------------------------------------------------------------------------------- /target/classes/ThreadPoolTrader.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/ThreadPoolTrader.class -------------------------------------------------------------------------------- /target/classes/TicketSystemDemo$TicketSeller.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/TicketSystemDemo$TicketSeller.class -------------------------------------------------------------------------------- /target/classes/TicketSystemDemo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinQi0777/Juc-interview/bfe3d9b1c69da95be2018d115966fe903d2b5457/target/classes/TicketSystemDemo.class --------------------------------------------------------------------------------