From 7ed697d9290d5a9250cc3256f289c8657fc3186a Mon Sep 17 00:00:00 2001 From: whaifree <49432110+whaibetter@users.noreply.github.com> Date: Sun, 14 Apr 2024 11:58:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=8623=E3=80=8132?= =?UTF-8?q?=E3=80=81503=E3=80=81739=E3=80=8124=E4=B8=AA=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BA=86188?= =?UTF-8?q?=E9=A2=98=E7=9A=84=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=B9=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=E7=BA=BF=E7=A8=8B=E6=B5=8B=E8=AF=95=E7=B1=BB?= =?UTF-8?q?ThreadTest=E5=92=8CLeetCode123=E7=9A=84=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/whaifree/leetCode/Dynamic/Stock.java | 44 ++- .../leetCode/LinkedList/LeetCode160.java | 30 ++ .../redo/redo_24_4_13/LeetCode23.java | 64 ++++ .../redo/redo_24_4_13/LeetCode32.java | 102 ++++++ .../redo/redo_24_4_13/LeetCode337.java | 10 + .../redo/redo_24_4_13/LeetCode42.java | 80 +++++ .../redo/redo_24_4_13/LeetCode496.java | 55 ++++ .../redo/redo_24_4_13/LeetCode503.java | 45 +++ .../redo/redo_24_4_13/LeetCode739.java | 43 +++ .../redo/redo_24_4_13/LeetCode84.java | 88 +++++ .../cn/whaifree/test/ThreadLocalExample.java | 2 + .../java/cn/whaifree/test/ThreadTest.java | 302 ++++++++++++++++++ 12 files changed, 852 insertions(+), 13 deletions(-) create mode 100644 src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode160.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode23.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode32.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode337.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode42.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode496.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode503.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode739.java create mode 100644 src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode84.java create mode 100644 src/main/java/cn/whaifree/test/ThreadTest.java diff --git a/src/main/java/cn/whaifree/leetCode/Dynamic/Stock.java b/src/main/java/cn/whaifree/leetCode/Dynamic/Stock.java index 5d97066..401c5b8 100644 --- a/src/main/java/cn/whaifree/leetCode/Dynamic/Stock.java +++ b/src/main/java/cn/whaifree/leetCode/Dynamic/Stock.java @@ -15,31 +15,49 @@ public class Stock { @Test public void test() { -// int[] prices = {7,1,5,3,6,4}; - int[] prices = {1,2,3,4,5}; - System.out.println(new LeetCode123_.Solution().maxProfit(prices)); + System.out.println(new LeetCode188_.Solution().maxProfit(2, new int[]{3,2,6,5,0,3})); } } class LeetCode188_{ - class Solution { + static class Solution { public int maxProfit(int k, int[] prices) { // dp[i][j] 表示第i天交易第k次的最大收益 - // dp[i][0] 表示第i天第 0/2 +1 次持有的最大手头 - // dp[i][1] 表示第i天第 1/2 +1次未持有的最大手头 + // dp[i][1] 表示第i天第 1/2 +1 次持有的最大手头 + // dp[i][0] 表示第i天第 0/2 +1次未持有的最大手头 - int[][] dp = new int[prices.length][k * 2]; + // dp[i][0] = max dp[i-1][0] dp[i-1][1]+prices[i] + // dp[i][1] = max dp[i-1][1] dp[i-1][0]-prices[i] + // dp[i][2] = max dp[i-1][2] dp[i-1][1]+prices[i] + // dp[i][3] = max dp[i-1][3] dp[i-1][2]-prices[i] + + int[][] dp = new int[prices.length][k * 2 + 1]; // 未持有 初始化 - for (int i = 0; i < prices.length; i += 2) { - dp[i][0] = -prices[0]; + for (int i = 1; i <= k * 2; i += 2) { + dp[0][i] = -prices[0]; } - for (int i = 0; i < prices.length; i++) { - for (int j = 0; j < k * 2; j++) { - + for (int i = 1; i < prices.length; i++) { + for (int j = 0; j < k ; j++) { + int indexJ = 2 * j + 1; + dp[i][indexJ] = Math.max(dp[i - 1][indexJ], dp[i - 1][indexJ - 1] - prices[i]); + dp[i][indexJ + 1] = Math.max(dp[i - 1][indexJ + 1], dp[i - 1][indexJ] + prices[i]); } } - return 1; + return dp[prices.length - 1][k * 2]; + + // 假设k=2 +// int[][] dp = new int[prices.length][5]; +// // 4种状态 1 3 表示持有 +// dp[0][1] = -prices[0]; +// dp[0][3] = -prices[0]; +// for (int i = 1; i < prices.length; i++) { +// dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); +// dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]); +// dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] - prices[i]); +// dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]); +// } +// return dp[prices.length - 1][4]; } } } diff --git a/src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode160.java b/src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode160.java new file mode 100644 index 0000000..85664cf --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode160.java @@ -0,0 +1,30 @@ +package cn.whaifree.leetCode.LinkedList; + +import cn.whaifree.leetCode.model.ListNode; +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 11:06 + * @注释 + */ +public class LeetCode160 { + + @Test + public void test() + { + + } + + class Solution { + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + ListNode A = headA, B = headB; + while (A != B) { + A = A == null ? headB : A.next; + B = B == null ? headA : B.next; + } + return A; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode23.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode23.java new file mode 100644 index 0000000..7ce2243 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode23.java @@ -0,0 +1,64 @@ +package cn.whaifree.redo.redo_24_4_13; + +import cn.whaifree.leetCode.model.ListNode; +import org.junit.Test; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 13:49 + * @注释 + */ +public class LeetCode23 { + + @Test + public void test() { + new Solution().mergeKLists( + new ListNode[]{ + ListNode.listNodeFromArray(new int[]{1, 4, 5}) + , ListNode.listNodeFromArray(new int[]{1, 3, 4}) + , ListNode.listNodeFromArray(new int[]{2, 6}) + } + ).printList(); + + } + + class Solution { + public ListNode mergeKLists(ListNode[] lists) { + // 优先队列 + PriorityQueue queue = new PriorityQueue<>( + new Comparator() { + @Override + public int compare(ListNode o1, ListNode o2) { + return o1.val - o2.val; + } + } + ); + + // 优先队列内出来就是最大的头部 + for (ListNode list : lists) { + if (list != null) { + queue.add(list); + } + } + + ListNode pre = new ListNode(-1); + ListNode preIndex = pre; + while (!queue.isEmpty()) { + ListNode poll = queue.poll(); + preIndex.next = poll; + preIndex = preIndex.next; + if (poll.next != null) { + queue.add(poll.next); + } + } + + return pre.next; + } + } + + +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode32.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode32.java new file mode 100644 index 0000000..e1e8606 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode32.java @@ -0,0 +1,102 @@ +package cn.whaifree.redo.redo_24_4_13; + +import org.junit.Test; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 14:14 + * @注释 + */ +public class LeetCode32 { + + @Test + public void test() + { + Solution solution = new Solution(); + int i = solution.longestValidParentheses("()(()"); + System.out.println(i); + } + + class Solution { + public int longestValidParentheses(String s) { + /** + * 找到匹配 + * 最长 + */ + boolean[] flag = new boolean[s.length()]; + Deque stack = new LinkedList<>(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + stack.push(i); + }else if (!stack.isEmpty()) { + flag[stack.pop()] = true; + flag[i] = true; + } + } + + // 统计flag连续出现的 + int longMax = 0; + int flagIndex = 0; + for (int i = 0; i < flag.length; i++) { + if (flag[i]) { + flagIndex++; + }else { + flagIndex = 0; + } + longMax = Math.max(longMax, flagIndex); + } + + return longMax; + } + } + class Solution1 { + + /** + * 计数器, + * 计算左括号右括号的数量,如果右括号数量更多就重置 + * @param s + * @return + */ + public int longestValidParentheses(String s) { + int left = 0, right = 0, maxlength = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + left++; + }else if (s.charAt(i) == ')') { + right++; + } + if (right > left) { + left = 0; + right = 0; + } + if (right == left) { + maxlength = Math.max(maxlength, 2 * left); + } + } + + left = 0; + right = 0; + for (int i = s.length() - 1; i >= 0; i--) { + if (s.charAt(i) == '(') { + left++; + }else if (s.charAt(i) == ')') { + right++; + } + if (left > right) { + left = 0; + right = 0; + } + if (left == right) { + maxlength = Math.max(maxlength, 2 * right); + } + } + + + return maxlength; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode337.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode337.java new file mode 100644 index 0000000..4661cf5 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode337.java @@ -0,0 +1,10 @@ +package cn.whaifree.redo.redo_24_4_13; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/14 11:55 + * @注释 + */ +public class LeetCode337 { +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode42.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode42.java new file mode 100644 index 0000000..0e9cd5b --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode42.java @@ -0,0 +1,80 @@ +package cn.whaifree.redo.redo_24_4_13; + +import org.junit.Test; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 11:10 + * @注释 + */ +public class LeetCode42 { + @Test + public void test() + { + int[] height = {0,1,0,2,1,0,1,3,2,1,2,1}; + System.out.println(new Solution1().trap(height)); + } + + class Solution { + public int trap(int[] height) { + // 接下雨水,寻找凹陷处 + Deque stack = new LinkedList<>(); + /* int[] he = new int[height.length + 2]; + for (int i = 1; i < height.length + 1; i++) { + he[i] = height[i - 1]; + } + height = he;*/ + + stack.push(0); + int res = 0; + for (int i = 0; i < height.length; i++) { + if (height[stack.peek()] < height[i]) { + while (!stack.isEmpty()&&height[stack.peek()] < height[i]) { + int mid = stack.pop(); + if (!stack.isEmpty()) { + int right = i; + int left = stack.peek(); + int w = right - left - 1; + int h = (Math.min(height[left], height[right]) - height[mid]); + res += w * h; + } + } + stack.push(i); + }else { + stack.push(i); + } + + } + return res; + } + } + + class Solution1 { + public int trap(int[] height) { + + int[] left = new int[height.length]; + int[] right = new int[height.length]; + // 从左到右获取左边左边最小 + int max = Integer.MIN_VALUE; + for (int i = 0; i < height.length; i++) { + max = Math.max(max, height[i]); + left[i] = max; + } + max = Integer.MIN_VALUE; + for (int i = height.length - 1; i >= 0; i--) { + max = Math.max(max, height[i]); + right[i] = max; + } + int res = 0; + for (int i = 0; i < height.length; i++) { + res += (Math.min(left[i], right[i]) - height[i]); + } + return res; + } + } + +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode496.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode496.java new file mode 100644 index 0000000..f6703e4 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode496.java @@ -0,0 +1,55 @@ +package cn.whaifree.redo.redo_24_4_13; + +import org.junit.Test; + +import java.util.Deque; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 13:05 + * @注释 + */ +public class LeetCode496 { + + @Test + public void test() + { + int[] nums1 = {4,1,2}; + int[] nums2 = {1,3,4,2}; + int[] res = new Solution().nextGreaterElement(nums1, nums2); + for (int i : res) { + System.out.println(i); + } + } + + class Solution { + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + // nums1对应位置的下一个更大元素 + Map map = new HashMap<>(); + Deque stack = new LinkedList<>(); + stack.push(nums2[0]); + for (int i = 1; i < nums2.length; i++) { + while (!stack.isEmpty() && nums2[i] > stack.peek()) { + map.put(stack.pop(), nums2[i]); + } + stack.push(nums2[i]); + } + int[] res = new int[nums1.length]; + for (int i = 0; i < nums1.length; i++) { + int key = nums1[i]; + if (map.containsKey(key)) { + res[i] = map.get(key); + } else { + res[i] = -1; + } + } + return res; + } + } + + +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode503.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode503.java new file mode 100644 index 0000000..b15b156 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode503.java @@ -0,0 +1,45 @@ +package cn.whaifree.redo.redo_24_4_13; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Deque; +import java.util.LinkedList; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 13:29 + * @注释 + */ +public class LeetCode503 { + @Test + public void test() + { + int[] nums = new int[]{1,2,3,4,3}; + Solution solution = new Solution(); + int[] res = solution.nextGreaterElements(nums); + for (int i : res) { + System.out.println(i); + } + } + + class Solution { + public int[] nextGreaterElements(int[] nums) { + Deque stack = new LinkedList<>(); + stack.push(0); + int[] res = new int[nums.length]; + Arrays.fill(res, -1); + + int len = nums.length; + int length = len * 2; + for (int i = 1; i < length; i++) { + while (!stack.isEmpty() && nums[i % len] > nums[stack.peek()]) { + res[stack.pop()] = nums[i % len]; + } + stack.push(i % len); + } + return res; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode739.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode739.java new file mode 100644 index 0000000..481ac52 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode739.java @@ -0,0 +1,43 @@ +package cn.whaifree.redo.redo_24_4_13; + +import org.junit.Test; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 13:37 + * @注释 + */ +public class LeetCode739 { + + @Test + public void test() + { + int[] temperatures = {73, 74, 75, 71, 69, 72, 76, 73}; + int[] ints = new Solution().dailyTemperatures(temperatures); + for (int anInt : ints) { + System.out.println(anInt); + } + } + + + // 下一个更高温度出现在几天后 + class Solution { + public int[] dailyTemperatures(int[] temperatures) { + int[] ans = new int[temperatures.length]; + Deque stack = new LinkedList<>(); + stack.push(0); + for (int i = 1; i < temperatures.length; i++) { + while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) { + Integer pop = stack.pop(); + ans[pop] = i - pop; + } + stack.push(i); + } + return ans; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode84.java b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode84.java new file mode 100644 index 0000000..4f43771 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_24_4_13/LeetCode84.java @@ -0,0 +1,88 @@ +package cn.whaifree.redo.redo_24_4_13; + +import org.junit.Test; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 11:43 + * @注释 + */ +public class LeetCode84 { + + @Test + public void test() + { + int[] heights = {2,1,5,6,2,3}; + int i = new Solution1().largestRectangleArea(heights); + System.out.println(i); + } + + class Solution { + public int largestRectangleArea(int[] heights) { + int[] he = new int[heights.length + 2]; + System.arraycopy(heights, 0, he, 1, heights.length); + heights = he; + + Deque stack = new LinkedList<>(); + // 找到凸点 + stack.push(0); + int maxR = 0; + for (int i = 1; i < heights.length; i++) { + if (heights[i] < heights[stack.peek()]) { + while (!stack.isEmpty() && heights[i] < heights[stack.peek()]) { + // 找到下坡后,挨个弹出栈(这个出栈位置的就是高),判断新的面积会不会更大 + int mid = stack.pop(); + if (!stack.isEmpty()) { + int left = stack.peek(); + int right = i; + int h = heights[mid]; + maxR = Math.max(maxR, (right - left - 1) * h); + } + } + + } + stack.push(i); + + } + return maxR; + + } + } + + class Solution1 { + public int largestRectangleArea(int[] heights) { + // 每个记录左边第一个小于本身的位置 + int[] left = new int[heights.length]; + int[] right = new int[heights.length]; + left[0] = -1; + for (int i = 1; i < heights.length; i++) { + int index = i - 1; + while (index >= 0 && heights[index] >= heights[i]) { + index = left[index]; + } + left[i] = index; + } + // 每个记录右边边第一个小于本身的位置 + right[heights.length - 1] = heights.length; + for (int i = heights.length - 2; i >= 0; i--) { + int index = i + 1; + while (index <= heights.length - 1 && heights[index] >= heights[i]) { + index = right[index]; + } + right[i] = index; + } + + int maxD = 0; + for (int i = 0; i < heights.length; i++) { + int leftIndex = left[i]; + int rightIndex = right[i]; + maxD = Math.max(maxD, (rightIndex - leftIndex - 1) * heights[i]); + } + return maxD; + } + } +} diff --git a/src/main/java/cn/whaifree/test/ThreadLocalExample.java b/src/main/java/cn/whaifree/test/ThreadLocalExample.java index bf17879..4767ddf 100644 --- a/src/main/java/cn/whaifree/test/ThreadLocalExample.java +++ b/src/main/java/cn/whaifree/test/ThreadLocalExample.java @@ -1,6 +1,8 @@ package cn.whaifree.test; public class ThreadLocalExample { + // 使用Lambda表达式与withInitial()方法指定初始值 + private static final ThreadLocal threadLocal = ThreadLocal.withInitial(() -> "Default Value from Lambda"); public static void main(String[] args) throws InterruptedException { for(int i=0 ; i<3; i++){ diff --git a/src/main/java/cn/whaifree/test/ThreadTest.java b/src/main/java/cn/whaifree/test/ThreadTest.java new file mode 100644 index 0000000..4b2382a --- /dev/null +++ b/src/main/java/cn/whaifree/test/ThreadTest.java @@ -0,0 +1,302 @@ +package cn.whaifree.test; + +import java.util.concurrent.Semaphore; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/4/13 16:06 + * @注释 + */ +public class ThreadTest { + + private static Object lock = new Object(); + private static Integer count = 0; + + /** + * 主函数示例,演示了通过两个线程交替打印字符并控制其执行顺序的简单并发程序。 + * 使用一个共享计数器和一个对象锁来协调两个线程的执行。 + * 线程1打印字符'a',线程2打印字符'b',交替进行,直到计数器达到100。 + * + * @param args 命令行参数(未使用) + * @throws InterruptedException 如果线程在等待时被中断则抛出此异常 + */ + public static void main1(String[] args) throws InterruptedException{ + + // 启动线程1,负责打印'a'并进行同步控制 + new Thread( + new Runnable() { + @Override + public void run() { + while (count < 100) { + synchronized (lock) { + // 当计数器为偶数时,线程1等待 + if (count % 2 == 0) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + System.out.println("a"); + count++; + // 计数器为奇数时,唤醒等待的线程2 + lock.notify(); + } + } + } + } + ).start(); + + // 启动线程2,负责打印'b'并进行同步控制 + new Thread( + new Runnable() { + @Override + public void run() { + while (count < 100) { + synchronized (lock) { + // 当计数器为奇数时,线程2等待 + if (count % 2 != 0) { + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + System.out.println("b"); + count++; + // 计数器为偶数时,唤醒等待的线程1 + lock.notify(); + } + } + } + } + ).start(); + + + } + + public static void main3(String[] args) throws InterruptedException{ + + // 创建三个线程 + Thread threadA = new Thread(() -> { + try { + // 循环100次 + for (int i = 0; i < 100; i++) { + // 获取锁 + synchronized (lock) { + // 判断是否轮到自己执行 + while (count % 3 != 0) { + // 不是则等待 + lock.wait(); + } + // 打印字母 + System.out.println("A"); + // 修改状态 + count++; + // 唤醒下一个线程 + lock.notifyAll(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + Thread threadB = new Thread(() -> { + try { + for (int i = 0; i < 100; i++) { + synchronized (lock) { + while (count % 3 != 1) { + lock.wait(); + } + System.out.println("B"); + count++; + lock.notifyAll(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + Thread threadC = new Thread(() -> { + try { + for (int i = 0; i < 100; i++) { + synchronized (lock) { + // 确保严格到本线程打的时候再等候 + while (count % 3 != 2) { + lock.wait(); + } + System.out.println("C"); + count++; + lock.notifyAll(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + // 启动三个线程 + threadA.start(); + threadB.start(); + threadC.start(); + + } + + private static final Semaphore semaphoreC = new Semaphore(2); // 初始化为0,表示开始时阻止线程2(打印'b')执行 + private static final Semaphore semaphoreA = new Semaphore(1); // 初始化为1,表示开始时允许线程1(打印'a')执行 + private static final Semaphore semaphoreB = new Semaphore(0); // 初始化为0,表示开始时阻止线程2(打印'b')执行 + public static void main2(String[] args) throws InterruptedException { + + new Thread( + () -> { + for (int i = 0; i < 50; i++) { + try { + semaphoreA.acquire(); + System.out.println("a"); + semaphoreB.release(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + ).start(); + + + new Thread( + () -> { + for (int i = 0; i < 50; i++) { + try { + semaphoreB.acquire(); + System.out.println("b"); + semaphoreA.release(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + ).start(); + } + +// public static void main(String[] args) throws InterruptedException{ +// +// new Thread( +// new Runnable() { +// @Override +// public void run() { +// while (count < 100) { +// synchronized (count) { +// System.out.println(count); +// if (count % 2 == 0) { +// try { +// count.wait(); +// } catch (InterruptedException e) { +// throw new RuntimeException(e); +// } +// } +// System.out.println("a"); +// count++; +// count.notify(); +// } +// } +// } +// } +// ).start(); +// new Thread( +// new Runnable() { +// @Override +// public void run() { +// while (count < 100) { +// synchronized (count) { +// System.out.println(count); +// if (count % 2 != 0) { +// try { +// count.wait(); // 此时就释放锁了 +// +// } catch (InterruptedException e) { +// throw new RuntimeException(e); +// } +// } +// +// System.out.println("b"); +// count++; +// count.notify(); +// } +// } +// } +// } +// ).start(); +// +// +// } + + + public static void main(String[] args) { + new Thread( + () -> { + while (count < 100) { + while (count % 3 == 0) { + System.out.println("A"); + count++; + } + } + } + ).start(); + new Thread( + () -> { + while (count < 100) { + while (count % 3 == 1) { + System.out.println("B"); + count++; + } + } + } + ).start(); + new Thread( + () -> { + while (count < 100) { + while (count % 3 == 2) { + System.out.println("C"); + count++; + } + } + } + ).start(); + } +} + +class DidLock{ + + public static void main(String[] args) { + Object a = new Object(); + Object b = new Object(); + new Thread( + ()->{ + synchronized (a) { + try { + System.out.println(Thread.currentThread().getName() + "a"); + Thread.sleep(100); + synchronized (b) { + + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + ).start(); + + new Thread( + ()->{ + synchronized (b) { + System.out.println(Thread.currentThread().getName() + "b"); + synchronized (a) { + + } + } + } + ).start(); + } +}