feat: 添加了LeetCode96, LeetCode416, LeetCode53, LeetCode135, LeetCode219, LeetCode406, LeetCode36四个Java类,分别对应LeetCode题目中的解法;

feat: 添加了FutureRelative类,用于演示Java中的Future和CompletableFuture用法;
feat: 添加了Solution1和Solution两个类,分别对应LeetCode36题目的两种解法;

Default Changelist
AffinityThreadPoolTest.java
FutureRelative.java
LeetCode36.java
LeetCode45.java
LeetCode53.java
LeetCode96.java
LeetCode134.java
LeetCode135.java
LeetCode219.java
LeetCode406.java
LeetCode416.java
LeetCode763.java
LeetCode968.java
LeetCode1005.java
P1.java
SocketDemo.java
This commit is contained in:
whaifree 2024-09-27 11:00:46 +08:00
parent 2219024e1b
commit 61d92b60d5
16 changed files with 1185 additions and 0 deletions

View File

@ -0,0 +1,64 @@
package cn.whaifree.interview.HS.Qz;
import java.util.Scanner;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 18:56
* @注释
*/
public class P1 {
public static void main(String[] args) {
// a + b = c 一只c a*b 的最大值
Scanner scanner = new Scanner(System.in);
long i = scanner.nextLong();
long maxProduct = 0;
for (int j = 0; j <= i; j++) {
long b = i - j;
long product = b * j;
maxProduct = Math.max(product, maxProduct);
}
System.out.println(maxProduct);
}
}
class p2{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext hasNextLine 的区别
int n = in.nextInt();
int k = in.nextInt();
if (n <= 1) {
System.out.println(-1);
return;
}
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = in.nextInt();
}
int tmp = 0;
for (int i = 1; i < nums.length; i++) {
int search = search(nums[i], nums[i - 1]);
if (search != -1) {
tmp = Math.max(search, tmp);
}
}
System.out.println(tmp);
}
public static int search(int a, int b) {
int tmp = Math.min(a, b);
while (tmp > 0) {
if (a % tmp == 0 && b % tmp == 0) {
return tmp;
}
tmp--;
}
return -1;
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.redo.redo_all_240924;
import java.util.Arrays;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/25 18:12
* @注释
*/
public class LeetCode1005 {
public static void main(String[] args) {
LeetCode1005 leetCode1005 = new LeetCode1005();
int[] nums = {2,-3,-1,5,-4};
int k = 2;
int i = leetCode1005.new Solution().largestSumAfterKNegations(nums, k);
System.out.println(i);
}
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
// 偶数
// 奇数
// 最小的绝对值
int absMin = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
if (nums[i] < 0 && k > 0) {
nums[i] = -nums[i];
k--;
}
absMin = Math.min(absMin, Math.abs(nums[i]));
}
int sum = Arrays.stream(nums).sum();
// 如果还有k没使用到
// 按照绝对值排序
if (k % 2 == 0) {
return sum;
}else {
return sum - absMin * 2;
}
}
}
}

View File

@ -0,0 +1,48 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/25 17:53
* @注释
*/
public class LeetCode134 {
@Test
public void test() {
int[] gas = {4,5, 1, 2, 3, };
int[] cost = { 1,2, 3, 4, 5,};
System.out.println(new Solution().canCompleteCircuit(gas, cost));
}
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int sumGas = 0;
for (int j : gas) {
sumGas += j;
}
int sumCost = 0;
for (int j : cost) {
sumCost += j;
}
if (sumCost > sumGas) {
return -1;
}
// 包能走到
int now = 0;
int startNow = 0;
for (int i = 0; i < gas.length; i++) {
now += gas[i];
if (now < cost[i]) {
now = 0;
startNow = i + 1;
}else {
now -= cost[i];
}
}
return startNow;
}
}
}

View File

@ -0,0 +1,39 @@
package cn.whaifree.redo.redo_all_240924;
import java.util.Arrays;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 11:37
* @注释
*/
public class LeetCode135 {
class Solution {
/**
*
*
* @param ratings
* @return
*/
public int candy(int[] ratings) {
int[] distribute = new int[ratings.length];
Arrays.fill(distribute, 1);
for (int i = 1; i < ratings.length; i++) {
if (distribute[i] > distribute[i - 1]) {
distribute[i] = distribute[i - 1] + 1;
}
}
for (int i = ratings.length - 2; i >= 0; i++) {
if (distribute[i] > distribute[i + 1]) {
distribute[i] = Math.max(distribute[i], distribute[i + 1] + 1);
}
}
return Arrays.stream(distribute).sum();
}
}
}

View File

@ -0,0 +1,43 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 14:43
* @注释
*/
public class LeetCode219 {
@Test
public void test() {
int[] nums = {1, 2, 3, 9, 8, 7, 1};
int k = 3;
System.out.println(new Solution().containsNearbyDuplicate(nums, k));
}
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (!map.containsKey(nums[i])) {
map.put(nums[i], new ArrayList<>());
}
List<Integer> list = map.get(nums[i]);
for (int j = 0; j < list.size(); j++) {
if (Math.abs(i - list.get(j)) <= k) {
return true;
}
}
list.add(i);
}
return false;
}
}
}

View File

@ -0,0 +1,111 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.HashSet;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 14:53
* @注释
*/
public class LeetCode36 {
@Test
public void test() {
char[][] board = new char[][]{
{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
{'.', '9', '8', '.', '.', '.', '.', '6', '.'},
{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
{'7', '.', '.', '.', '2', '.', '.', '.', '6'},
{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
{'.', '.', '.', '.', '8', '.', '.', '7', '9'}
};
System.out.println(new Solution().isValidSudoku(board));
}
class Solution1 {
public boolean isValidSudoku(char[][] board) {
//直接用数组记录每个行九宫格内数字出现的次数
int[][] row = new int[9][9];
int[][] col = new int[9][9];
int[][][] sub = new int[3][3][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char c = board[i][j];
if (c != '.') {
int numIndex = c - '0' - 1;
row[i][numIndex]++;
col[j][numIndex]++;
sub[i / 3][j / 3][numIndex]++;
if (row[i][numIndex] > 1 || col[j][numIndex] > 1 || sub[i / 3][j / 3][numIndex] > 1) {
return false;
}
}
}
}
return true;
}
}
class Solution {
public boolean isValidSudoku(char[][] board) {
int length = board.length;
for (int i = 0; i < length; i++) {
HashSet<Character> set = new HashSet<>();
for (int j = 0; j < length; j++) {
char c = board[i][j];
if (set.contains(c)) {
return false;
}
if (c != '.') {
set.add(c);
}
}
}
for (int i = 0; i < length; i++) {
HashSet<Character> set = new HashSet<>();
for (int j = 0; j < length; j++) {
char c = board[j][i];
if (set.contains(c)) {
return false;
}
if (c != '.') {
set.add(c);
}
}
}
for (int i = 0; i < length; i += 3) {
for (int j = 0; j < length; j += 3) {
HashSet<Character> set = new HashSet<>();
int x = i;
int y = j;
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
int newX = x + k;
int newY = y + l;
char c = board[newX][newY];
if (set.contains(c)) {
return false;
}
if (c != '.') {
set.add(c);
}
}
}
}
}
return true;
}
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 12:20
* @注释
*/
public class LeetCode406 {
@Test
public void test()
{
int[][] people = {{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}};
Solution solution = new Solution();
int[][] result = solution.reconstructQueue(people);
System.out.println(Arrays.deepToString(result));
}
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if (o2[0] == o1[0]) {
return o1[1] - o2[1];
}
return o2[0] - o1[0];
}
});
List<int[]> list = new ArrayList<>();
for (int[] person : people) {
list.add(person[1], person);
}
return list.toArray(new int[list.size()][2]);
}
}
}

View File

@ -0,0 +1,105 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.Arrays;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 13:40
* @注释
*/
public class LeetCode416 {
@Test
public void test() {
int[] nums = {1,2,8,5};
System.out.println(new Solution1().canPartition(nums));
}
class Solution {
/**
*
*
* @param nums
* @return
*/
public boolean canPartition(int[] nums) {
Arrays.sort(nums);
int sum = Arrays.stream(nums).sum();
if (sum%2==1){
return false;
}
int target = sum / 2;
// 背包容量 target
// 物品 nums
int[][] dp = new int[nums.length][target + 1];
// dp[i][j] 表示从0-i任意选择放入容量为j的背包的最大价值
for (int i = nums[0]; i <= target; i++) {
dp[0][i] = nums[0];
}
for (int i = 1; i < nums.length; i++) {
for (int j = 1; j <= target; j++) {
if (j > nums[i]) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);
}else {
dp[i][j] = dp[i - 1][j];
}
if (dp[i][j] == target) {
return true;
}
}
}
return dp[nums.length - 1][target] == target;
}
}
class Solution1 {
/**
*
*
* @param nums
* @return
*/
public boolean canPartition(int[] nums) {
// Arrays.sort(nums);
int sum = Arrays.stream(nums).sum();
if (sum % 2 == 1) {
return false;
}
int target = sum / 2;
// 背包容量 target
// 物品 nums
int[] dp = new int[target + 1];
// dp[i][j] 表示从0-i任意选择放入容量为j的背包的最大价值
for (int i = nums[0]; i <= target; i++) {
dp[i] = nums[0];
}
for (int i = 1; i < nums.length; i++) {
for (int j = target; j > 0; j--) {
if (j > nums[i]) {
dp[j] = Math.max(dp[j - nums[i]] + nums[i], dp[j]);
}
if (dp[j] == target) {
return true;
}
}
}
return dp[target] == target;
}
}
}

View File

@ -0,0 +1,63 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/25 16:38
* @注释
*/
public class LeetCode45 {
@Test
public void test() {
int[] nums = {2, 3, 1, 1, 4};
System.out.println(new Solution().jump(nums));
}
class Solution {
public int jump(int[] nums) {
int curCover = 0;
int maxCover = 0;
int jump = 0;
for (int i = 0; i < nums.length; i++) {
maxCover = Math.max(i + nums[i], maxCover);
if (i == curCover) {
jump++;
curCover = maxCover;
}
if (curCover >= nums.length - 1) {
return jump;
}
}
return jump;
}
}
class Solution1 {
public int jump(int[] nums) {
int left = 0;
int right = 0;
int jump = 0;
int minJump = Integer.MAX_VALUE;
while (left < nums.length) {
int tmpFar = left + nums[left];
// 找到每一跳最远能覆盖到哪贪心
while (left <= right) {
tmpFar = Math.max(tmpFar, left + nums[right]);
left++;
}
jump++;
if (tmpFar >= nums.length - 1) {
minJump = Math.min(minJump, jump);
break;
}
right = tmpFar;
}
return minJump == Integer.MAX_VALUE ? 1 : minJump;
}
}
}

View File

@ -0,0 +1,41 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/25 12:37
* @注释
*/
public class LeetCode53 {
@Test
public void test() {
int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
System.out.println(new Solution().maxSubArray(nums));
}
class Solution {
/**
*
* dp[i] 表示以i结尾的最大连续子数组的最大和
*
* -2,1,-3,4,-1,2,1,-5,4
* -2 1 -2 4 3 5 6 1 5
*
* @param nums
* @return
*/
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int nowMax = nums[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
nowMax = Math.max(nowMax, dp[i]);
}
return nowMax;
}
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 12:49
* @注释
*/
public class LeetCode763 {
@Test
public void test() {
String s = "ababcbacadefegdehijhklij";
List<Integer> list = new Solution().partitionLabels(s);
System.out.println(list);
}
class Solution {
public List<Integer> partitionLabels(String s) {
char[] charArray = s.toCharArray();
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0; i < charArray.length; i++) {
map.put(charArray[i], i);
}
List<Integer> list = new ArrayList<>();
int left = 0;
int right = 0;
int rightMax = 0;
while (right < charArray.length) {
Integer last = map.get(charArray[right]);
rightMax = Math.max(rightMax, last); // 这个区间内最远的出现范围
if (right == last && right == rightMax) {
list.add(right - left + 1);
left = right + 1;
}
right++;
}
return list;
}
}
}

View File

@ -0,0 +1,61 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 13:22
* @注释
*/
public class LeetCode96 {
@Test
public void test() {
Solution solution = new Solution();
int numTrees = solution.numTrees(5);
System.out.println(numTrees);
}
class Solution {
/**
* dp[0] = 1;
* dp[1] = 1;
* dp[2] = 2;
* dp[3] =
* 左边0 * 右边2
* 左边1 * 右边1
* 左边2 * 右边0
*
* dp[k] =
* i=0-k-1
* 左边i * 右边k-i-1
* 左边i+1 * 右边k-i-2
* ...
* 左边0 * 右边k-1
*
* @param n
* @return
*/
public int numTrees(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
for (int k = 3; k < dp.length; k++) {
int sum = 0;
for (int i = 0; i < k; i++) {
sum += dp[i] * dp[k - i - 1];
}
dp[k] = sum;
}
return dp[n];
}
}
}

View File

@ -0,0 +1,66 @@
package cn.whaifree.redo.redo_all_240924;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/26 13:00
* @注释
*/
public class LeetCode968 {
@Test
public void test()
{
TreeNode root = TreeNode.constructTreeByArray(0,0,null,0,null,0,null,null,0);
System.out.println(new Solution().minCameraCover(root));
}
class Solution {
int res = 0;
public int minCameraCover(TreeNode root) {
return anInt(root) == 3 ? res + 1 : res;
}
/**
*
* 1 被覆盖
* 2 有监控
* 3 没有监控没有被覆盖
*
* 1 & 1 3
* 1 | 2 1
* 1 | 3 2
* 2 | 3 2
* 2 & 2 1
* 3 & 3 2
*
* @param root
* @return -1不装 1
*
*/
public int anInt(TreeNode root) {
if (root == null) {
return 1; // 空节点表示被覆盖上面那个节点才能表示没有被监控
}
int left = anInt(root.left);
int right = anInt(root.right);
if (left == 1 && right == 1) {
return 3;
}
if (left == 2 && right == 2) {
return 1;
}
if (left == 3 || right == 3) {
res++;
// 子树有没被覆盖的就需要加监控
return 2;
}
return 1;
}
}
}

View File

@ -0,0 +1,320 @@
package cn.whaifree.tech.NetWorkSocket;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/25 21:54
* @注释
*/
public class SocketDemo {
}
class BIOSocketClient{
/**
* 主方法用于启动Socket客户端连接到指定的服务器并进行数据传输
* @param args 命令行参数
*/
public static void main(String[] args) {
String serverName = "localhost"; // 服务器地址
int port = 12130; // 服务器端口
try(Scanner scanner = new Scanner(System.in)) // 创建扫描器用于读取用户输入
{
System.out.println("连接到主机:" + serverName + " ,端口号:" + port);
Socket client = new java.net.Socket(serverName, port); // 创建Socket连接
System.out.println("远程主机地址:" + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream(); // 获取输出流
DataOutputStream out = new DataOutputStream(outToServer); // 包装输出流以便发送UTF-8编码的字符串
while (scanner.hasNext()) { // 循环读取用户输入
String next = scanner.next();
out.writeUTF("" + client.getLocalSocketAddress() + "发送消息: " + next); // 发送消息到服务器
if (next.equals("end")) { // 如果用户输入end则结束循环
break;
}
}
InputStream inFromServer = client.getInputStream(); // 获取输入流
DataInputStream in = new DataInputStream(inFromServer); // 包装输入流以便读取UTF-8编码的字符串
System.out.println("服务器响应: " + in.readUTF()); // 读取并打印服务器响应
client.close(); // 关闭Socket连接
}catch(IOException e)
{
e.printStackTrace(); // 打印异常信息
}
}
}
class BIOSocketServer{
private static ServerSocket serverSocket; // 服务器Socket
/**
* 静态初始化块用于创建并配置服务器Socket
*/
static {
try
{
serverSocket = new ServerSocket(12130); // 创建服务器Socket并绑定端口
serverSocket.setSoTimeout(10000); // 设置Socket超时时间为10秒
}catch(IOException e)
{
e.printStackTrace(); // 打印异常信息
}
}
/**
* 主方法用于启动Socket服务器监听客户端连接并处理数据传输
* @param args 命令行参数
*/
public static void main(String[] args) {
while(true) // 无限循环等待客户端连接
{
try
{
System.out.println("等待远程连接,端口号为:" + serverSocket.getLocalPort() + "...");
try (Socket server = serverSocket.accept()) { // 接受客户端连接
System.out.println("远程主机地址:" + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream()); // 获取输入流
String message = in.readUTF(); // 读取客户端消息
while (!"end".equals(message)) { // 循环读取直到客户端发送end
System.out.println("客户端发送的消息: " + message);
message = in.readUTF();
}
DataOutputStream out = new DataOutputStream(server.getOutputStream()); // 获取输出流
out.writeUTF("谢谢连接我:" + server.getLocalSocketAddress() + "\nGoodbye!"); // 发送响应给客户端
}
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!"); // 打印超时信息
break; // 超时则退出循环
}catch(IOException e)
{
e.printStackTrace(); // 打印异常信息
break; // 异常则退出循环
}
}
}
}
class NIOServer{
/**
* 主函数用于启动服务器并监听客户端连接及处理消息
* @param args 命令行参数
* @throws IOException 如果发生IO异常
*/
public static void main(String[] args) throws IOException {
// 定义服务器监听的端口号
int port = 12140;
// 创建服务端服务器套接字通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 绑定端口号到服务器套接字
serverSocketChannel.socket().bind(new InetSocketAddress(port));
// 设置通道为非阻塞模式
serverSocketChannel.configureBlocking(false);
// 打开一个选择器
Selector selector = Selector.open();
// 将服务器套接字通道注册到选择器关注接受事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 持续监听和处理连接及读取事件
while (true) {
// 监听并处理就绪事件
selector.select();
// 获取发生事件的键集合
Set<SelectionKey> selectedKeys = selector.selectedKeys();
// 遍历集合中的每一个事件
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
// 获取当前事件
SelectionKey key = iterator.next();
// 移除已处理的事件
iterator.remove();
// 如果有新的连接请求
if (key.isAcceptable()) {
// 获取服务器套接字通道
ServerSocketChannel server = (ServerSocketChannel) key.channel();
// 接受新的客户端连接
SocketChannel socketChannel = server.accept();
// 设置通道为非阻塞模式
socketChannel.configureBlocking(false);
// 将客户端通道注册到选择器关注读取事件
socketChannel.register(selector, SelectionKey.OP_READ);
// 输出新连接的客户端地址
System.out.println("新客户端连接:" + socketChannel.getRemoteAddress());
}
// 如果有可读取的事件
if (key.isReadable()) {
// 获取客户端套接字通道
SocketChannel socketChannel = (SocketChannel) key.channel();
// 创建缓冲区以读取数据
ByteBuffer buffer = ByteBuffer.allocate(1024);
int read;
StringBuilder message = new StringBuilder();
// 读取客户端发送的数据
while ((read = socketChannel.read(buffer)) > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
message.append(new String(bytes));
buffer.clear();
}
// 如果读取到-1表示客户端已关闭连接
if (read == -1) {
socketChannel.close();
continue;
}
// 如果接收到的消息为"end"关闭连接
if (message.toString().equals("end")) {
socketChannel.close();
continue;
}
// 输出客户端发送的消息
System.out.println("客户端发送的消息: " + message);
// 准备响应数据并写入客户端通道
ByteBuffer response = ByteBuffer.wrap(("服务器响应: " + message).getBytes());
socketChannel.write(response);
}
}
}
}
}
class AIOServer{
// 服务器端口常量
private static final int PORT = 12140;
/**
* 主函数用于启动AIO服务器
* @param args 命令行参数
* @throws InterruptedException 主线程睡眠时可能抛出的异常
* @throws IOException 网络操作可能抛出的异常
*/
public static void main(String[] args) throws InterruptedException, IOException {
// 创建并绑定异步服务器Socket通道
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open()
.bind(new java.net.InetSocketAddress(PORT));
System.out.println("服务器启动在端口 " + PORT);
// 开始监听客户端连接
server.accept(null, new AcceptHandler(server));
// 做其他事情
// 由于AIO是非阻塞的这里需要让主线程保持运行状态
Thread.sleep(Long.MAX_VALUE);
}
/**
* 处理客户端连接请求的完成事件
*/
static class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, Object> {
private final AsynchronousServerSocketChannel server;
/**
* 构造函数初始化服务器通道
* @param server 服务器通道
*/
public AcceptHandler(AsynchronousServerSocketChannel server) {
this.server = server;
}
/**
* 当连接成功完成时的处理逻辑
* @param client 成功连接的客户端通道
* @param attachment 附加数据通常用于传递状态或进行进一步处理
*/
@Override
public void completed(AsynchronousSocketChannel client, Object attachment) {
System.out.println("客户端连接成功");
// 读取客户端发送的数据
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
/**
* 当读取操作成功完成时的处理逻辑
* @param result 读取到的字节数
* @param buffer 用于读取的缓冲区
*/
@Override
public void completed(Integer result, ByteBuffer buffer) {
buffer.flip(); // 在缓冲区Buffer中切换读写模式
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
String received = new String(data);
System.out.println("从客户端接收: " + received);
buffer.clear();
if ("end".equals(received.trim())) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
ByteBuffer response = ByteBuffer.wrap(("服务器响应: " + received).getBytes());
client.write(response, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
System.out.println("数据发送成功");
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
}
client.read(buffer, buffer, this);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
// 处理读取失败情况此处未定义具体行为
}
});
server.accept(null, this);
}
/**
* 当连接请求失败时的处理逻辑
* @param exc 异常对象
* @param attachment 附加数据
*/
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
}
}

View File

@ -22,6 +22,8 @@ public class AffinityThreadPoolTest {
ExecutorService executorService = Executors.newFixedThreadPool(8); ExecutorService executorService = Executors.newFixedThreadPool(8);
long l = System.currentTimeMillis(); long l = System.currentTimeMillis();
synchronized (o) { synchronized (o) {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
int finalI = i; int finalI = i;

View File

@ -0,0 +1,81 @@
package cn.whaifree.tech.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.Supplier;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/9/25 13:36
* @注释
*/
public class FutureRelative {
final static ExecutorService executorService = Executors.newFixedThreadPool(10,
Executors.defaultThreadFactory());
public static void main(String[] args) {
futureTaskDemo();
}
public static void futureTaskDemo() {
List<FutureTask> futureTasks = new ArrayList<>();
for (int i = 0; i < 100; i++) {
FutureTask futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
return 1;
}
});
futureTasks.add(futureTask);
executorService.submit(futureTask);
}
for (FutureTask futureTask : futureTasks) {
try {
System.out.println(futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
static volatile int num = 0;
public static void completeFutureDemo() {
List<CompletableFuture<Integer>> completableFutures = new ArrayList<>();
for (int i = 0; i < 100; i++) {
CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(new Supplier<Integer>() {
@Override
public Integer get() {
return num++;
}
}, executorService).exceptionally(
throwable -> {
System.out.println("error");
return 0;
}
);
completableFutures.add(cf);
}
// CompletableFuture<Void> allOf = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]));
int sum = 0;
for (CompletableFuture<Integer> cf : completableFutures) {
try {
sum += cf.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}