Initial commit

This commit is contained in:
2025-11-06 10:32:28 +08:00
commit 1f42e79061
112 changed files with 5101 additions and 0 deletions

204
.gitignore vendored Normal file
View File

@@ -0,0 +1,204 @@
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
### MicrosoftOffice ###
*.tmp
# Word temporary
~$*.doc*
# Word Auto Backup File
Backup of *.doc*
# Excel temporary
~$*.xls*
# Excel Backup File
*.xlk
# PowerPoint temporary
~$*.ppt*
# Visio autosave temporary files
*.~vsd*
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk

29
Classwork/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
Classwork/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

5
Classwork/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
Classwork/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Classwork.iml" filepath="$PROJECT_DIR$/Classwork.iml" />
</modules>
</component>
</project>

4
Classwork/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

11
Classwork/Classwork.iml Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,40 @@
package Bank;
public class Bank {
private int money;
private String name;
public Bank(String name, int money) {
this.name = name;
this.money = money;
}
public synchronized void deposit(int m) {
money += m;
}
public synchronized boolean withdraw(int m) {
if (money >= m) {
money -= m;
check();
return true;
} else {
return false;
}
}
public String getName() {
return name;
}
private void check() {
if (money < 0) {
System.out.println("可用余额为负数money=" + money);
}
/*
else {
System.out.println("money=" + money);
}
*/
}
}

View File

@@ -0,0 +1,17 @@
package Bank;
public class ClientThread extends Thread{
private Bank bank;
public ClientThread(Bank bank) {
this.bank = bank;
}
@Override
public void run(){
while (true){
boolean ok=bank.withdraw(1000);
if(ok){
bank.deposit(1000);
}
}
}
}

View File

@@ -0,0 +1,15 @@
package Bank;
public class MainTest {
public static void main(String[] args) {
Bank bank = new Bank("a bad bank", 1000);
new ClientThread(bank).start();
new ClientThread(bank).start();
new ClientThread(bank).start();
new ClientThread(bank).start();
new ClientThread(bank).start();
new ClientThread(bank).start();
new ClientThread(bank).start();
new ClientThread(bank).start();
}
}

View File

@@ -0,0 +1,45 @@
package Buffer;
import java.nio.ByteBuffer;
import static Buffer.BufferOperation.bufferToString;
public class BufferCreateIO {
public static void main(String[] args) {
ByteBuffer buffer = ByteBuffer.allocate(10);
System.out.println("初始状态: " + bufferToString(buffer));
// 向缓冲区依次写入字节 1, 2, 3, 4, 5
buffer.put((byte) 1);
buffer.put((byte) 2);
buffer.put((byte) 3);
buffer.put((byte) 4);
buffer.put((byte) 5);
System.out.println("写入5个字节后: " + bufferToString(buffer));
// 切换为读模式
buffer.flip();
System.out.println("调用flip()后 (读模式): " + bufferToString(buffer));
// 读取并打印所有数据
System.out.print("读取数据: ");
while (buffer.hasRemaining()) {
System.out.print(buffer.get() + " ");
}
System.out.println("\n读取完毕后: " + bufferToString(buffer));
// 清空缓冲区
buffer.clear();
System.out.println("调用clear()后: " + bufferToString(buffer));
// 验证是否可重新写入
buffer.put((byte) 6);
System.out.println("重新写入一个字节 (6) 后: " + bufferToString(buffer));
buffer.flip();
System.out.print("读取新写入的数据: ");
while (buffer.hasRemaining()) {
System.out.print(buffer.get() + " ");
}
System.out.println();
}
}

View File

@@ -0,0 +1,24 @@
package Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
public class BufferOperation {
public static String bufferToString(ByteBuffer buffer) {
return "pos=" + buffer.position() + " lim=" + buffer.limit() + " cap=" + buffer.capacity();
}
public static String charBufferToString(CharBuffer buffer) {
return "pos=" + buffer.position() + " lim=" + buffer.limit() + " cap=" + buffer.capacity();
}
public static String intBufferToString(IntBuffer buffer) {
return "pos=" + buffer.position() + " lim=" + buffer.limit() + " cap=" + buffer.capacity();
}
public static String bytesToHex(byte[] bytes, int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(String.format("%02X ", bytes[i]));
}
return sb.toString().trim();
}
}

View File

@@ -0,0 +1,56 @@
package Data;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Data {
private final char[] buffer;
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
public Data(int size) {
this.buffer = new char[size];
for (int i = 0; i < buffer.length; i++) {
buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
readLock.lock();
try {
return doRead();
} finally {
readLock.unlock();
}
}
public void write(char c) throws InterruptedException {
writeLock.lock();
try {
doWrite(c);
} finally {
writeLock.unlock();
}
}
private char[] doRead() throws InterruptedException {
char[] newbuf = new char[buffer.length];
for (int i = 0; i < buffer.length; i++) {
newbuf[i] = buffer[i];
}
slowly();
return newbuf;
}
private void doWrite(char c) throws InterruptedException {
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
slowly();
}
}
private void slowly() throws InterruptedException {
Thread.sleep(50);
}
}

View File

@@ -0,0 +1,40 @@
package Data;
public class Main {
public static void main(String[] args) {
Data data = new Data(10);
ReaderThread reader1 = new ReaderThread("Reader-1", data);
ReaderThread reader2 = new ReaderThread("Reader-2", data);
ReaderThread reader3 = new ReaderThread("Reader-3", data);
ReaderThread reader4 = new ReaderThread("Reader-4", data);
WriterThread writer1 = new WriterThread("Writer-A", data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
WriterThread writer2 = new WriterThread("Writer-B", data, "abcdefghijklmnopqrstuvwxyz");
System.out.println("Starting threads...");
reader1.start();
reader2.start();
writer1.start();
reader3.start();
reader4.start();
writer2.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("\nInterrupting threads...");
reader1.interrupt();
reader2.interrupt();
reader3.interrupt();
reader4.interrupt();
writer1.interrupt();
writer2.interrupt();
System.out.println("Main thread finished.");
}
}

View File

@@ -0,0 +1,24 @@
package Data;
public class ReaderThread extends Thread {
private final Data data;
public ReaderThread(String name, Data data) {
super(name);
this.data = data;
}
@Override
public void run() {
try {
while (true) {
char[] readBuf = data.read();
System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted.");
Thread.currentThread().interrupt();
}
}
}

View File

@@ -0,0 +1,37 @@
package Data;
public class WriterThread extends Thread {
private final Data data;
private final String filler;
private int index = 0;
public WriterThread(String name, Data data, String filler) {
super(name);
this.data = data;
this.filler = filler;
}
@Override
public void run() {
try {
while (true) {
char c = nextChar();
data.write(c);
System.out.println(Thread.currentThread().getName() + " writes " + c);
Thread.sleep(300);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted.");
Thread.currentThread().interrupt();
}
}
private char nextChar() {
char c = filler.charAt(index);
index++;
if (index >= filler.length()) {
index = 0;
}
return c;
}
}

View File

@@ -0,0 +1,63 @@
package DataLimited;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Data {
private final char[] buffer;
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
private final Semaphore readSemaphore = new Semaphore(3);
public Data(int size) {
this.buffer = new char[size];
for (int i = 0; i < buffer.length; i++) {
buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
readSemaphore.acquire();
try {
readLock.lock();
try {
return doRead();
} finally {
readLock.unlock();
}
} finally {
readSemaphore.release();
}
}
public void write(char c) throws InterruptedException {
writeLock.lock();
try {
doWrite(c);
} finally {
writeLock.unlock();
}
}
private char[] doRead() throws InterruptedException {
char[] newbuf = new char[buffer.length];
for (int i = 0; i < buffer.length; i++) {
newbuf[i] = buffer[i];
}
slowly();
return newbuf;
}
private void doWrite(char c) throws InterruptedException {
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
slowly();
}
}
private void slowly() throws InterruptedException {
Thread.sleep(50);
}
}

View File

@@ -0,0 +1,40 @@
package DataLimited;
public class Main {
public static void main(String[] args) {
Data data = new Data(10);
ReaderThread reader1 = new ReaderThread("Reader-1", data);
ReaderThread reader2 = new ReaderThread("Reader-2", data);
ReaderThread reader3 = new ReaderThread("Reader-3", data);
ReaderThread reader4 = new ReaderThread("Reader-4", data);
WriterThread writer1 = new WriterThread("Writer-A", data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
WriterThread writer2 = new WriterThread("Writer-B", data, "abcdefghijklmnopqrstuvwxyz");
System.out.println("Starting threads...");
reader1.start();
reader2.start();
writer1.start();
reader3.start();
reader4.start();
writer2.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("\nInterrupting threads...");
reader1.interrupt();
reader2.interrupt();
reader3.interrupt();
reader4.interrupt();
writer1.interrupt();
writer2.interrupt();
System.out.println("Main thread finished.");
}
}

View File

@@ -0,0 +1,24 @@
package DataLimited;
public class ReaderThread extends Thread {
private final Data data;
public ReaderThread(String name, Data data) {
super(name);
this.data = data;
}
@Override
public void run() {
try {
while (true) {
char[] readBuf = data.read();
System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));
Thread.sleep(100);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted.");
Thread.currentThread().interrupt();
}
}
}

View File

@@ -0,0 +1,37 @@
package DataLimited;
public class WriterThread extends Thread {
private final Data data;
private final String filler;
private int index = 0;
public WriterThread(String name, Data data, String filler) {
super(name);
this.data = data;
this.filler = filler;
}
@Override
public void run() {
try {
while (true) {
char c = nextChar();
data.write(c);
System.out.println(Thread.currentThread().getName() + " writes " + c);
Thread.sleep(300);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted.");
Thread.currentThread().interrupt();
}
}
private char nextChar() {
char c = filler.charAt(index);
index++;
if (index >= filler.length()) {
index = 0;
}
return c;
}
}

View File

@@ -0,0 +1,19 @@
package ProducerConsumer.extthread;
import ProducerConsumer.service.RepastService;
public class ThreadC extends Thread {
private RepastService service;
public ThreadC(RepastService service) {
super();
this.service = service;
}
@Override
public void run() {
service.get();
}
}

View File

@@ -0,0 +1,19 @@
package ProducerConsumer.extthread;
import ProducerConsumer.service.RepastService;
public class ThreadP extends Thread {
private RepastService service;
public ThreadP(RepastService service) {
super();
this.service = service;
}
@Override
public void run() {
service.set();
}
}

View File

@@ -0,0 +1,94 @@
package ProducerConsumer.service;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class RepastService {
volatile private Semaphore setSemaphore = new Semaphore(10);// 厨师
volatile private Semaphore getSemaphore = new Semaphore(20);// 就餐者
volatile private ReentrantLock lock = new ReentrantLock();
volatile private Condition setCondition = lock.newCondition();
volatile private Condition getCondition = lock.newCondition();
volatile private Object[] producePosition = new Object[4];
private boolean isEmpty() {
boolean isEmpty = true;
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] != null) {
isEmpty = false;
break;
}
}
if (isEmpty == true) {
return true;
} else {
return false;
}
}
private boolean isFull() {
boolean isFull = true;
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] == null) {
isFull = false;
break;
}
}
return isFull;
}
public void set() {
try {
// System.out.println("set");
setSemaphore.acquire();// 允许同时最多有10个厨师进行生产
lock.lock();
while (isFull()) {
System.out.println("生产者在等待");
setCondition.await();
}
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] == null) {
producePosition[i] = "数据";
System.out.println(Thread.currentThread().getName()
+ " 生产了 " + producePosition[i]);
break;
}
}
getCondition.signalAll();
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
setSemaphore.release();
}
}
public void get() {
try {
// System.out.println("get");
getSemaphore.acquire();// 允许同时最多有16个就餐者
lock.lock();
while (isEmpty()) {
System.out.println("消费者在等待");
getCondition.await();
}
for (int i = 0; i < producePosition.length; i++) {
if (producePosition[i] != null) {
System.out.println(Thread.currentThread().getName()
+ " 消费了 " + producePosition[i]);
producePosition[i] = null;
break;
}
}
setCondition.signalAll();
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
getSemaphore.release();
}
}
}

View File

@@ -0,0 +1,24 @@
package ProducerConsumer.test.run;
import ProducerConsumer.service.RepastService;
import ProducerConsumer.extthread.ThreadC;
import ProducerConsumer.extthread.ThreadP;
public class Run {
public static void main(String[] args) throws InterruptedException {
RepastService service = new RepastService();
ThreadP[] arrayP = new ThreadP[60];
ThreadC[] arrayC = new ThreadC[60];
for (int i = 0; i < 60; i++) {
arrayP[i] = new ThreadP(service);
arrayC[i] = new ThreadC(service);
}
Thread.sleep(2000);
for (int i = 0; i < 60; i++) {
arrayP[i].start();
arrayC[i].start();
}
}
}

View File

@@ -0,0 +1,88 @@
package Race;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class TortoiseHareRace {
private static final int RACE_LENGTH = 100; // 赛道长度(米)
private static int tortoisePosition = 0; // 乌龟位置
private static int harePosition = 0; // 兔子位置
private static boolean raceFinished = false; // 比赛是否结束
private static final Object lock = new Object(); // 同步锁
public static void main(String[] args) {
Random random = new Random();
// 乌龟线程:速度慢但稳定
Thread tortoise = new Thread(() -> {
while (!raceFinished) {
synchronized (lock) {
// 乌龟每次移动1-2米
int step = random.nextInt(2) + 1;
tortoisePosition += step;
System.out.println("乌龟前进了" + step + "米,当前位置:" + tortoisePosition + "");
if (tortoisePosition >= RACE_LENGTH) {
raceFinished = true;
System.out.println("乌龟赢得了比赛!");
}
}
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "乌龟");
// 兔子线程:速度快但会休息
Thread hare = new Thread(() -> {
while (!raceFinished) {
synchronized (lock) {
// 兔子移动速度更快每次移动5-10米
int step = random.nextInt(6) + 5;
harePosition += step;
System.out.println("兔子前进了" + step + "米,当前位置:" + harePosition + "");
if (harePosition >= RACE_LENGTH) {
raceFinished = true;
System.out.println("兔子赢得了比赛!");
}
}
// 兔子有30%的概率会休息
if (random.nextInt(10) < 3) {
int restTime = random.nextInt(600) + 200;
System.out.println("兔子太自信了,休息" + restTime + "毫秒");
try {
TimeUnit.MILLISECONDS.sleep(restTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "兔子");
System.out.println("比赛开始!");
tortoise.start();
hare.start();
try {
tortoise.join();
hare.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("比赛结束!");
System.out.println("最终结果 - 乌龟:" + Math.min(tortoisePosition, RACE_LENGTH) +
"米,兔子:" + Math.min(harePosition, RACE_LENGTH) + "");
}
}

View File

@@ -0,0 +1,78 @@
package RedPacket;
import java.util.Random;
public class AICRedPacketGrabber {
private static int totalMoney = 100;
private static int thread1Money = 0;
private static int thread2Money = 0;
private static final Object lock = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
grabMoney(true);
}
}, "线程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
grabMoney(false);
}
}, "线程2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1抢到的总金额: " + thread1Money + "");
System.out.println("线程2抢到的总金额: " + thread2Money + "");
System.out.println("剩余金额: " + totalMoney + "");
}
private static void grabMoney(boolean isThread1) {
Random random = new Random();
while (true) {
synchronized (lock) {
if (totalMoney < 1) {
break;
}
int grabMoney = random.nextInt(3) + 1;
if (grabMoney > totalMoney) {
grabMoney = totalMoney;
}
totalMoney -= grabMoney;
if (isThread1) {
thread1Money += grabMoney;
System.out.println("线程1抢到了" + grabMoney + "元,剩余" + totalMoney + "");
} else {
thread2Money += grabMoney;
System.out.println("线程2抢到了" + grabMoney + "元,剩余" + totalMoney + "");
}
if (totalMoney == 0) {
break;
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,91 @@
package RedPacket;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.*;
public class CFRedPacketGrabber {
private static int totalMoney = 100;
private static final Object lock = new Object();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入参与抢红包的线程数: ");
int threadCount = scanner.nextInt();
scanner.close();
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 0; i < threadCount; i++) {
final int threadId = i + 1;
Future<Integer> future = executor.submit(new RedPacketGrabber(threadId));
futures.add(future);
}
int[] threadMoney = new int[threadCount];
try {
for (int i = 0; i < threadCount; i++) {
threadMoney[i] = futures.get(i).get();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
for (int i = 0; i < threadCount; i++) {
System.out.println("线程" + (i + 1) + "抢到的总金额: " + threadMoney[i] + "");
}
System.out.println("剩余金额: " + totalMoney + "");
}
static class RedPacketGrabber implements Callable<Integer> {
private final int threadId;
private int moneyGrabbed = 0;
public RedPacketGrabber(int threadId) {
this.threadId = threadId;
}
@Override
public Integer call() {
Random random = new Random();
String threadName = "线程" + threadId;
while (true) {
synchronized (lock) {
if (totalMoney < 1) {
break;
}
int grabMoney = random.nextInt(3) + 1;
if (grabMoney > totalMoney) {
grabMoney = totalMoney;
}
totalMoney -= grabMoney;
moneyGrabbed += grabMoney;
System.out.println(threadName + "抢到了" + grabMoney + "元,剩余" + totalMoney + "");
if (totalMoney == 0) {
break;
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return moneyGrabbed;
}
}
}

View File

@@ -0,0 +1,82 @@
package RedPacket;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.*;
public class LambdaRedPacketGrabber {
private static int totalMoney = 100;
private static final Object lock = new Object();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入参与抢红包的线程数: ");
int threadCount = scanner.nextInt();
scanner.close();
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 0; i < threadCount; i++) {
final int threadId = i + 1;
Future<Integer> future = executor.submit(() -> {
Random random = new Random();
String threadName = "线程" + threadId;
int moneyGrabbed = 0;
while (true) {
synchronized (lock) {
if (totalMoney < 1) {
break;
}
int grabMoney = random.nextInt(3) + 1;
if (grabMoney > totalMoney) {
grabMoney = totalMoney;
}
totalMoney -= grabMoney;
moneyGrabbed += grabMoney;
System.out.println(threadName + "抢到了" + grabMoney + "元,剩余" + totalMoney + "");
if (totalMoney == 0) {
break;
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return moneyGrabbed;
});
futures.add(future);
}
int[] threadMoney = new int[threadCount];
try {
for (int i = 0; i < threadCount; i++) {
threadMoney[i] = futures.get(i).get();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
for (int i = 0; i < threadCount; i++) {
System.out.println("线程" + (i + 1) + "抢到的总金额: " + threadMoney[i] + "");
}
System.out.println("剩余金额: " + totalMoney + "");
}
}

View File

@@ -0,0 +1,76 @@
package RedPacket;
import java.util.Random;
public class OrderedRedPacketGrabber {
private static int totalMoney = 100;
private static int thread1Money = 0;
private static int thread2Money = 0;
private static boolean isThread1Turn = true;
private static final Object lock = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> grabMoney(true), "线程1");
Thread thread2 = new Thread(() -> grabMoney(false), "线程2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1抢到的总金额: " + thread1Money + "");
System.out.println("线程2抢到的总金额: " + thread2Money + "");
System.out.println("剩余金额: " + totalMoney + "");
}
private static void grabMoney(boolean isThread1) {
Random random = new Random();
while (true) {
synchronized (lock) {
while (isThread1Turn != isThread1 && totalMoney >= 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (totalMoney < 1) {
lock.notifyAll();
break;
}
int grabMoney = random.nextInt(3) + 1;
if (grabMoney > totalMoney) {
grabMoney = totalMoney;
}
totalMoney -= grabMoney;
if (isThread1) {
thread1Money += grabMoney;
System.out.println("线程1抢到了" + grabMoney + "元,剩余" + totalMoney + "");
} else {
thread2Money += grabMoney;
System.out.println("线程2抢到了" + grabMoney + "元,剩余" + totalMoney + "");
}
isThread1Turn = !isThread1Turn;
lock.notify();
if (totalMoney == 0) {
lock.notifyAll();
break;
}
}
}
}
}

View File

@@ -0,0 +1,67 @@
package RedPacket;
import java.util.Random;
public class RandomRedPacketGrabber {
private static int totalMoney = 100;
private static int thread1Money = 0;
private static int thread2Money = 0;
private static final Object lock = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> grabMoney(true), "线程1");
Thread thread2 = new Thread(() -> grabMoney(false), "线程2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1抢到的总金额: " + thread1Money + "");
System.out.println("线程2抢到的总金额: " + thread2Money + "");
System.out.println("剩余金额: " + totalMoney + "");
}
private static void grabMoney(boolean isThread1) {
Random random = new Random();
while (true) {
synchronized (lock) {
if (totalMoney < 1) {
break;
}
int grabMoney = random.nextInt(3) + 1;
if (grabMoney > totalMoney) {
grabMoney = totalMoney;
}
totalMoney -= grabMoney;
if (isThread1) {
thread1Money += grabMoney;
System.out.println("线程1抢到了" + grabMoney + "元,剩余" + totalMoney + "");
} else {
thread2Money += grabMoney;
System.out.println("线程2抢到了" + grabMoney + "元,剩余" + totalMoney + "");
}
if (totalMoney == 0) {
break;
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,88 @@
package RedPacket;
import java.util.Random;
import java.util.concurrent.*;
public class ThreadPoolRedPacketGrabber {
private static int totalMoney = 100;
private static final int THREAD_COUNT = 2;
private static final Object lock = new Object();
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
int[] threadMoney = new int[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
final int threadId = i;
executor.submit(new RedPacketGrabber(threadId, threadMoney, latch));
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
for (int i = 0; i < THREAD_COUNT; i++) {
System.out.println("线程" + (i + 1) + "抢到的总金额: " + threadMoney[i] + "");
}
System.out.println("剩余金额: " + totalMoney + "");
}
static class RedPacketGrabber implements Runnable {
private final int threadId;
private final int[] threadMoney;
private final CountDownLatch latch;
public RedPacketGrabber(int threadId, int[] threadMoney, CountDownLatch latch) {
this.threadId = threadId;
this.threadMoney = threadMoney;
this.latch = latch;
}
@Override
public void run() {
try {
Random random = new Random();
String threadName = "线程" + (threadId + 1);
while (true) {
synchronized (lock) {
if (totalMoney < 1) {
break;
}
int grabMoney = random.nextInt(3) + 1;
if (grabMoney > totalMoney) {
grabMoney = totalMoney;
}
totalMoney -= grabMoney;
threadMoney[threadId] += grabMoney;
System.out.println(threadName + "抢到了" + grabMoney + "元,剩余" + totalMoney + "");
if (totalMoney == 0) {
break;
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
} finally {
latch.countDown();
}
}
}
}

29
Final/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

10
Final/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 依赖于环境的 Maven 主目录路径
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
Final/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
Final/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Final.iml" filepath="$PROJECT_DIR$/Final.iml" />
</modules>
</component>
</project>

124
Final/.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

4
Final/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

11
Final/Final.iml Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,108 @@
package aio;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
public class AIOChatClient {
private static final String HOST = "127.0.0.1";
private static final int PORT = 8888;
private AsynchronousSocketChannel clientChannel;
private CountDownLatch latch;
public void start() throws Exception {
clientChannel = AsynchronousSocketChannel.open();
latch = new CountDownLatch(1);
clientChannel.connect(new InetSocketAddress(HOST, PORT), null, new CompletionHandler<Void, Object>() {
@Override
public void completed(Void result, Object attachment) {
System.out.println("成功连接到服务器。现在可以开始聊天了(输入 'exit' 退出)。");
startRead();
startWrite();
}
@Override
public void failed(Throwable exc, Object attachment) {
System.err.println("连接服务器失败: " + exc.getMessage());
latch.countDown();
}
});
latch.await();
}
private void startRead() {
ByteBuffer buffer = ByteBuffer.allocate(1024);
clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
if (result > 0) {
attachment.flip();
String message = StandardCharsets.UTF_8.decode(attachment).toString();
System.out.println(message);
attachment.clear();
} else if (result == -1) {
handleDisconnect();
return;
}
if (clientChannel.isOpen()) {
clientChannel.read(attachment, attachment, this);
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.err.println("读取数据失败: " + exc.getMessage());
handleDisconnect();
}
});
}
private void startWrite() {
new Thread(() -> {
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
try {
String message;
while ((message = consoleReader.readLine()) != null) {
if ("exit".equalsIgnoreCase(message.trim())) {
break;
}
ByteBuffer buffer = StandardCharsets.UTF_8.encode(message);
clientChannel.write(buffer, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {}
@Override
public void failed(Throwable exc, Object attachment) {
System.err.println("发送消息失败: " + exc.getMessage());
handleDisconnect();
}
});
}
} catch (IOException e) {
e.printStackTrace();
} finally {
handleDisconnect();
}
}).start();
}
private void handleDisconnect() {
try {
if (clientChannel.isOpen()) {
clientChannel.close();
System.out.println("与服务器的连接已断开。");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
public static void main(String[] args) {
try {
new AIOChatClient().start();
} catch (Exception e) {
System.err.println("客户端启动时发生错误。");
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,127 @@
package aio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
public class AIOChatServer {
private static final int PORT = 8888;
private AsynchronousServerSocketChannel serverSocketChannel;
private final CopyOnWriteArrayList<AsynchronousSocketChannel> clients = new CopyOnWriteArrayList<>();
public void start() {
try {
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newFixedThreadPool(10));
serverSocketChannel = AsynchronousServerSocketChannel.open(group);
serverSocketChannel.bind(new InetSocketAddress(PORT));
System.out.println("服务器已启动,监听端口:" + PORT);
serverSocketChannel.accept(null, new AcceptHandler());
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
private class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, Object> {
@Override
public void completed(AsynchronousSocketChannel clientChannel, Object attachment) {
serverSocketChannel.accept(null, this);
clients.add(clientChannel);
try {
System.out.println("客户端 [" + clientChannel.getRemoteAddress() + "] 已连接。当前在线人数:" + clients.size());
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer buffer = ByteBuffer.allocate(1024);
clientChannel.read(buffer, new ClientSession(clientChannel, buffer), new ReadWriteHandler());
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("接受连接失败:" + exc);
}
}
private class ReadWriteHandler implements CompletionHandler<Integer, ClientSession> {
@Override
public void completed(Integer result, ClientSession session) {
if (result > 0) {
session.buffer.flip();
String receivedMessage = StandardCharsets.UTF_8.decode(session.buffer).toString().trim();
if (!receivedMessage.isEmpty()) {
String messageToSend;
try {
messageToSend = "客户端 [" + session.clientChannel.getRemoteAddress() + "] 说: " + receivedMessage;
System.out.println("正在广播: " + messageToSend);
broadcast(messageToSend, session.clientChannel);
} catch (IOException e) {
e.printStackTrace();
}
}
session.buffer.clear();
session.clientChannel.read(session.buffer, session, this);
} else if (result == -1) {
handleDisconnect(session.clientChannel);
}
}
@Override
public void failed(Throwable exc, ClientSession session) {
System.out.println("读写数据时发生错误:" + exc.getMessage());
handleDisconnect(session.clientChannel);
}
}
private void broadcast(String message, AsynchronousSocketChannel sender) {
ByteBuffer initialBuffer = StandardCharsets.UTF_8.encode(message);
for (AsynchronousSocketChannel client : clients) {
if (client.isOpen() && !client.equals(sender)) {
ByteBuffer bufferForWriting = initialBuffer.duplicate();
class WriteContext {
final AsynchronousSocketChannel clientChannel;
final ByteBuffer buffer;
WriteContext(AsynchronousSocketChannel client, ByteBuffer buf) {
this.clientChannel = client;
this.buffer = buf;
}
}
WriteContext context = new WriteContext(client, bufferForWriting);
client.write(bufferForWriting, context, new CompletionHandler<Integer, WriteContext>() {
@Override
public void completed(Integer result, WriteContext attachment) {
// 如果缓冲区中还有剩余数据,说明是一次“部分写”,需要继续发送
if (attachment.buffer.hasRemaining()) {
attachment.clientChannel.write(attachment.buffer, attachment, this);
}
}
@Override
public void failed(Throwable exc, WriteContext attachment) {
System.err.println("向客户端 " + attachment.clientChannel + " 广播消息失败: " + exc);
handleDisconnect(attachment.clientChannel);
}
});
}
}
}
private void handleDisconnect(AsynchronousSocketChannel clientChannel) {
clients.remove(clientChannel);
try {
System.out.println("客户端 [" + clientChannel.getRemoteAddress() + "] 已断开连接。当前在线人数:" + clients.size());
clientChannel.close();
} catch (IOException e) {
}
}
private static class ClientSession {
AsynchronousSocketChannel clientChannel;
ByteBuffer buffer;
public ClientSession(AsynchronousSocketChannel clientChannel, ByteBuffer buffer) {
this.clientChannel = clientChannel;
this.buffer = buffer;
}
}
public static void main(String[] args) {
new AIOChatServer().start();
}
}

View File

@@ -0,0 +1,96 @@
package aio;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class AsyncQueueDemo {
public static void main(String[] args) throws InterruptedException {
final int QUEUE_CAPACITY = 10;
final int PRODUCER_COUNT = 3;
final int CONSUMER_COUNT = 5;
final int ITEMS_PER_PRODUCER = 20;
AsyncQueue<String> queue = new AsyncQueue<>(QUEUE_CAPACITY);
ExecutorService producerExecutor = Executors.newFixedThreadPool(PRODUCER_COUNT);
ExecutorService consumerExecutor = Executors.newFixedThreadPool(CONSUMER_COUNT);
AtomicInteger producedCount = new AtomicInteger(0);
AtomicInteger consumedCount = new AtomicInteger(0);
System.out.println("启动 " + PRODUCER_COUNT + " 个生产者和 " + CONSUMER_COUNT + " 个消费者...");
for (int i = 0; i < PRODUCER_COUNT; i++) {
final int producerId = i + 1;
producerExecutor.submit(() -> {
for (int j = 0; j < ITEMS_PER_PRODUCER; j++) {
String item = "产品-" + producerId + "-" + (j + 1);
queue.putAsync(item).thenRun(() -> {
System.out.println("生产者 " + producerId + " 成功放入: " + item);
producedCount.incrementAndGet();
});
try {
Thread.sleep((long)(Math.random() * 100));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
for (int i = 0; i < CONSUMER_COUNT; i++) {
final int consumerId = i + 1;
consumerExecutor.submit(() -> {
while (consumedCount.get() < PRODUCER_COUNT * ITEMS_PER_PRODUCER) {
queue.takeAsync().thenAccept(item -> {
System.out.println("消费者 " + consumerId + " 成功取出: " + item);
consumedCount.incrementAndGet();
});
try {
Thread.sleep((long)(Math.random() * 200));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
producerExecutor.shutdown();
producerExecutor.awaitTermination(1, TimeUnit.MINUTES);
while (consumedCount.get() < PRODUCER_COUNT * ITEMS_PER_PRODUCER) {
Thread.sleep(100);
}
System.out.println("\n所有任务完成。");
System.out.println("总共生产: " + producedCount.get());
System.out.println("总共消费: " + consumedCount.get());
consumerExecutor.shutdownNow();
}
}
class AsyncQueue<T> {
private final BlockingQueue<T> queue;
private final ExecutorService executor = Executors.newCachedThreadPool();
public AsyncQueue(int capacity) {
this.queue = new ArrayBlockingQueue<>(capacity);
}
public CompletableFuture<Void> putAsync(T item) {
return CompletableFuture.runAsync(() -> {
try {
queue.put(item);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("放入队列时被中断", e);
}
}, executor);
}
public CompletableFuture<T> takeAsync() {
return CompletableFuture.supplyAsync(() -> {
try {
return queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("从队列取出时被中断", e);
}
}, executor);
}
public void shutdown() {
executor.shutdown();
}
}

View File

@@ -0,0 +1,47 @@
package multi_thread;
public class AlternatingPrint {
private final Object lock = new Object();
private int number = 1;
public static void main(String[] args) {
AlternatingPrint printer = new AlternatingPrint();
Thread oddThread = new Thread(printer::printOddNumbers, "奇数计数线程");
Thread evenThread = new Thread(printer::printEvenNumbers, "偶数计数线程");
oddThread.start();
evenThread.start();
}
public void printOddNumbers() {
synchronized (lock) {
while (number < 100) {
while (number % 2 == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("奇数计数线程中断.");
}
}
System.out.println(Thread.currentThread().getName() + ": " + number);
number++;
lock.notifyAll();
}
}
}
public void printEvenNumbers() {
synchronized (lock) {
while (number <= 100) {
while (number % 2 != 0) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("偶数计数线程中断.");
}
}
System.out.println(Thread.currentThread().getName() + ": " + number);
number++;
lock.notifyAll();
}
}
}
}

View File

@@ -0,0 +1,43 @@
package multi_thread;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
int numberOfWorkers = 3;
CountDownLatch latch = new CountDownLatch(numberOfWorkers);
System.out.println("主线程启动工作线程...");
for (int i = 1; i <= numberOfWorkers; i++) {
Thread worker = new Thread(new Worker(i, latch));
worker.start();
}
System.out.println("主线程正在等待工作线程结束...");
latch.await();
System.out.println("所有工作线程结束,主线程继续运行。");
}
}
class Worker implements Runnable {
private final int id;
private final CountDownLatch latch;
public Worker(int id, CountDownLatch latch) {
this.id = id;
this.latch = latch;
}
@Override
public void run() {
try {
System.out.println("multi_thread.Worker " + id + " 开始工作。");
int workTime = (int) (Math.random() * 3000) + 1000;
TimeUnit.MILLISECONDS.sleep(workTime);
System.out.println("multi_thread.Worker " + id + " 完成工作。");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("multi_thread.Worker " + id + " 被中断。");
} finally {
latch.countDown();
System.out.println("multi_thread.Worker " + id + " 执行计数器减一. 剩余: " + latch.getCount());
}
}
}

View File

@@ -0,0 +1,55 @@
package multi_thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ExecutorServiceDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<String>> futureList = new ArrayList<>();
int numberOfTasks = 5;
System.out.println("提交 " + numberOfTasks + " 个任务到线程池...");
for (int i = 1; i <= numberOfTasks; i++) {
Callable<String> task = new Task(i);
Future<String> future = executor.submit(task);
futureList.add(future);
}
System.out.println("所有任务已提交,获取结果...");
for (Future<String> future : futureList) {
try {
String result = future.get();
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
System.err.println("获取结果时出错 " + e.getMessage());
}
}
System.out.println("终止 executor service。");
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}
}
class Task implements Callable<String> {
private final int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public String call() throws Exception {
System.out.println("-> 任务 " + taskId + " 运行于线程: " + Thread.currentThread().getName());
TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 2000) + 500);
return "任务结果: " + taskId;
}
}

View File

@@ -0,0 +1,74 @@
package multi_thread;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
public class ProducerConsumer {
public static void main(String[] args) {
Buffer buffer = new Buffer(5);
Thread producerThread = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
buffer.produce(i);
Thread.sleep(new Random().nextInt(100));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("生产者被中断。");
}
}, "生产者");
Thread consumerThread = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
buffer.consume();
// 模拟消费耗时
Thread.sleep(new Random().nextInt(250));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("消费者被中断。");
}
}, "消费者");
producerThread.start();
consumerThread.start();
try {
producerThread.join();
consumerThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("主线程在等待时被中断。");
}
System.out.println("所有生产和消费任务完成。程序结束。");
}
}
class Buffer {
private final Queue<Integer> queue;
private final int capacity;
public Buffer(int capacity) {
this.queue = new LinkedList<>();
this.capacity = capacity;
}
public synchronized void produce(int item) throws InterruptedException {
while (queue.size() == capacity) {
System.out.println("缓冲区已满。" + Thread.currentThread().getName() + " 进入等待状态 (释放锁)...");
wait();
System.out.println(Thread.currentThread().getName() + " 已被唤醒!");
}
queue.add(item);
System.out.println(Thread.currentThread().getName() + " 生产了: " + item + " (当前容量: " + queue.size() + ")");
notifyAll();
}
public synchronized int consume() throws InterruptedException {
while (queue.isEmpty()) {
System.out.println("缓冲区为空。" + Thread.currentThread().getName() + " 进入等待状态 (释放锁)...");
wait();
System.out.println(Thread.currentThread().getName() + " 已被唤醒!");
}
int item = queue.poll();
System.out.println(Thread.currentThread().getName() + " 消费了: " + item + " (当前容量: " + queue.size() + ")");
notifyAll();
return item;
}
}

View File

@@ -0,0 +1,26 @@
package multi_thread;
public class StaticSyncCounter {
private static int count = 0;
public static synchronized void increment() {
count++;
}
public static void main(String[] args) throws InterruptedException {
int numThreads = 10;
int incrementsPerThread = 1000;
Thread[] threads = new Thread[numThreads];
for (int i = 0; i < numThreads; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < incrementsPerThread; j++) {
increment();
}
});
threads[i].start();
}
for (Thread thread : threads) {
thread.join();
}
System.out.println("期望计数: " + (numThreads * incrementsPerThread));
System.out.println("实际计数: " + count);
}
}

View File

@@ -0,0 +1,87 @@
package nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Scanner;
public class NioChatClient {
private static final int PORT = 8080;
private static final String HOST = "127.0.0.1";
private static final Charset CHARSET = Charset.forName("UTF-8");
public static void main(String[] args) {
try {
Selector selector = Selector.open();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress(HOST, PORT));
new Thread(() -> {
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("请输入要发送的消息...");
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if (message.length() > 0) {
socketChannel.write(CHARSET.encode(message));
}
}
} catch (IOException e) {
System.err.println("发送消息时发生错误: " + e.getMessage());
}
}).start();
while (true) {
if (selector.select() == 0) continue;
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isConnectable()) {
handleConnect(key, selector);
} else if (key.isReadable()) {
handleRead(key);
}
}
}
} catch (IOException e) {
System.err.println("客户端运行时发生错误: " + e.getMessage());
}
}
private static void handleConnect(SelectionKey key, Selector selector) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending()) {
channel.finishConnect();
}
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
System.out.println("成功连接到聊天服务器!");
}
private static void handleRead(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
StringBuilder content = new StringBuilder();
try {
int readBytes = channel.read(buffer);
if (readBytes > 0) {
buffer.flip();
content.append(CHARSET.decode(buffer));
System.out.println(content.toString());
} else if (readBytes == -1) {
System.out.println("服务器已关闭连接。");
key.cancel();
channel.close();
System.exit(0);
}
} catch (IOException e) {
System.out.println("读取服务器消息时出错,连接已断开。");
key.cancel();
channel.close();
System.exit(1);
}
}
}

View File

@@ -0,0 +1,109 @@
package nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.UUID;
public class NioChatServer {
private static final int PORT = 8080;
private static final String HOST = "127.0.0.1";
private static final Charset CHARSET = Charset.forName("UTF-8");
private static final ConcurrentHashMap<String, SocketChannel> clients = new ConcurrentHashMap<>();
public static void main(String[] args) {
try {
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(HOST, PORT));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("聊天服务器已启动,监听端口:" + PORT);
while (true) {
if (selector.select() == 0) continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
handleAccept(key, selector);
} else if (key.isReadable()) {
handleRead(key);
}
}
}
} catch (IOException e) {
System.err.println("服务器运行时发生错误: " + e.getMessage());
}
}
private static void handleAccept(SelectionKey key, Selector selector) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
SelectionKey clientKey = clientChannel.register(selector, SelectionKey.OP_READ);
String clientId = UUID.randomUUID().toString();
clients.put(clientId, clientChannel);
clientKey.attach(clientId);
System.out.println("客户端 [" + clientChannel.getRemoteAddress() + "] 连接成功。");
broadcastMessage("系统消息:欢迎 " + clientChannel.getRemoteAddress() + " 加入聊天室!当前在线人数:" + clients.size());
}
private static void handleRead(SelectionKey key) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
StringBuilder content = new StringBuilder();
try {
int readBytes = clientChannel.read(buffer);
if (readBytes > 0) {
buffer.flip();
content.append(CHARSET.decode(buffer));
String receivedMessage = content.toString();
String address = clientChannel.getRemoteAddress().toString();
String broadcastMsg = "来自 " + address + " 的消息: " + receivedMessage;
System.out.println(broadcastMsg);
broadcastMessage(broadcastMsg, clientChannel);
} else if (readBytes == -1) {
disconnectClient(key);
}
} catch (IOException e) {
disconnectClient(key);
}
}
private static void broadcastMessage(String message) {
broadcastMessage(message, null);
}
private static void broadcastMessage(String message, SocketChannel excludeChannel) {
for (SocketChannel channel : clients.values()) {
if (channel.isOpen() && (excludeChannel == null || !channel.equals(excludeChannel))) {
try {
channel.write(CHARSET.encode(message));
} catch (IOException e) {
System.err.println("向客户端发送消息失败: " + e.getMessage());
}
}
}
}
private static void disconnectClient(SelectionKey key) {
String clientId = (String) key.attachment();
SocketChannel clientChannel = (SocketChannel) key.channel();
try {
String address = clientChannel.getRemoteAddress().toString();
key.cancel();
clientChannel.close();
if (clientId != null) {
clients.remove(clientId);
}
System.out.println("客户端 [" + address + "] 已断开连接。");
broadcastMessage("系统消息:" + address + " 离开了聊天室。当前在线人数:" + clients.size());
} catch (IOException e) {
System.err.println("关闭客户端连接时出错: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,84 @@
package nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;
public class NioHttpServer {
private static final int PORT = 8081;
private static final String HOST = "127.0.0.1";
public static void main(String[] args) {
try {
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(HOST, PORT));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("HTTP服务器已启动监听端口" + PORT);
while (true) {
if (selector.select(3000) == 0) {
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (key.isAcceptable()) {
handleAccept(key, selector);
}
if (key.isReadable()) {
handleRead(key);
}
}
}
} catch (IOException e) {
System.err.println("HTTP服务器运行时发生错误: " + e.getMessage());
}
}
private static void handleAccept(SelectionKey key, Selector selector) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
System.out.println("接收到新的HTTP连接" + clientChannel.getRemoteAddress());
}
private static void handleRead(SelectionKey key) throws IOException {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
int bytesRead = clientChannel.read(buffer);
if (bytesRead > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String request = new String(bytes, StandardCharsets.UTF_8);
System.out.println("接收到HTTP请求:\n" + request);
String responseBody = "<h1>Hello NIO!</h1><p>这是一个基于Java NIO的HTTP服务器响应。</p>";
String httpResponse = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/html; charset=utf-8\r\n" +
"Content-Length: " + responseBody.getBytes(StandardCharsets.UTF_8).length + "\r\n" +
"\r\n" +
responseBody;
ByteBuffer responseBuffer = ByteBuffer.wrap(httpResponse.getBytes(StandardCharsets.UTF_8));
clientChannel.write(responseBuffer);
}
} catch (IOException e) {
System.err.println("处理请求时发生错误: " + e.getMessage());
} finally {
if (clientChannel != null) {
clientChannel.close();
}
key.cancel();
}
}
}

29
Homework0520/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

10
Homework0520/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 依赖于环境的 Maven 主目录路径
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
Homework0520/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
Homework0520/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Homework0520.iml" filepath="$PROJECT_DIR$/Homework0520.iml" />
</modules>
</component>
</project>

4
Homework0520/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,62 @@
import java.nio.ByteBuffer;
public class BufferBasicOperations {
public static void main(String[] args) {
// 创建一个容量为10的ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(10);
System.out.println("初始状态:");
printBufferStatus(buffer);
// 向缓冲区依次写入字节1, 2, 3, 4, 5
buffer.put((byte) 1);
buffer.put((byte) 2);
buffer.put((byte) 3);
buffer.put((byte) 4);
buffer.put((byte) 5);
System.out.println("\n写入数据后:");
printBufferStatus(buffer);
// 切换为读模式
buffer.flip();
System.out.println("\n切换为读模式后(flip):");
printBufferStatus(buffer);
// 读取并打印所有数据
System.out.println("\n读取的数据:");
while (buffer.hasRemaining()) {
byte data = buffer.get();
System.out.print(data + " ");
}
System.out.println();
System.out.println("\n读取完成后:");
printBufferStatus(buffer);
// 清空缓冲区
buffer.clear();
System.out.println("\n清空缓冲区后(clear):");
printBufferStatus(buffer);
// 验证是否可重新写入
buffer.put((byte) 100);
buffer.put((byte) 200);
System.out.println("\n重新写入数据后:");
printBufferStatus(buffer);
// 验证重新写入的数据
buffer.flip();
System.out.println("\n验证重新写入的数据:");
while (buffer.hasRemaining()) {
System.out.print(buffer.get() + " ");
}
System.out.println();
}
// 打印缓冲区状态
private static void printBufferStatus(ByteBuffer buffer) {
System.out.println("Position: " + buffer.position() +
", Limit: " + buffer.limit() +
", Capacity: " + buffer.capacity() +
", Remaining: " + buffer.remaining());
}
}

View File

@@ -0,0 +1,65 @@
import java.nio.CharBuffer;
public class BufferFlipCompact {
public static void main(String[] args) {
// 创建一个容量为8的CharBuffer
CharBuffer buffer = CharBuffer.allocate(8);
System.out.println("初始状态:");
printBufferStatus(buffer);
// 写入字符串"Hello"
buffer.put("Hello");
System.out.println("\n写入'Hello'后:");
printBufferStatus(buffer);
// 翻转缓冲区准备读取
buffer.flip();
System.out.println("\n翻转缓冲区后(flip):");
printBufferStatus(buffer);
// 读取前3个字符('H', 'e', 'l')
System.out.println("\n读取前3个字符:");
for (int i = 0; i < 3; i++) {
char c = buffer.get();
System.out.print(c + " ");
}
System.out.println();
System.out.println("\n读取3个字符后:");
printBufferStatus(buffer);
// 压缩缓冲区
buffer.compact();
System.out.println("\n压缩缓冲区后(compact):");
printBufferStatus(buffer);
// 再写入"World"
buffer.put("World");
System.out.println("\n写入'World'后:");
printBufferStatus(buffer);
// 翻转并打印最终缓冲区内容
buffer.flip();
System.out.println("\n最终缓冲区内容:");
while (buffer.hasRemaining()) {
System.out.print(buffer.get());
}
System.out.println();
// 显示完整的缓冲区内容(包括未读取的部分)
buffer.rewind(); // 回到开始位置
System.out.println("\n完整缓冲区内容:");
while (buffer.hasRemaining()) {
System.out.print(buffer.get());
}
System.out.println();
}
// 打印缓冲区状态
private static void printBufferStatus(CharBuffer buffer) {
System.out.println("Position: " + buffer.position() +
", Limit: " + buffer.limit() +
", Capacity: " + buffer.capacity() +
", Remaining: " + buffer.remaining());
}
}

View File

@@ -0,0 +1,105 @@
import java.nio.IntBuffer;
import java.nio.InvalidMarkException;
public class BufferMarkInvalid {
public static void main(String[] args) {
// 创建一个容量为3的IntBuffer
IntBuffer buffer = IntBuffer.allocate(3);
System.out.println("初始状态:");
printBufferStatus(buffer);
// 依次写入10、20
buffer.put(10);
buffer.put(20);
System.out.println("\n写入10、20后:");
printBufferStatus(buffer);
// 在写入20后调用mark()
buffer.mark();
System.out.println("\n调用mark()后 (position=2):");
printBufferStatus(buffer);
// 写入30
buffer.put(30);
System.out.println("\n写入30后:");
printBufferStatus(buffer);
// 调用reset(),验证是否能成功
try {
buffer.reset();
System.out.println("\n第一次reset()成功:");
printBufferStatus(buffer);
System.out.println("mark仍然有效position回到标记位置2");
} catch (InvalidMarkException e) {
System.out.println("\n第一次reset()失败: " + e.getMessage());
}
// 清空缓冲区
buffer.clear();
System.out.println("\n清空缓冲区后(clear):");
printBufferStatus(buffer);
// 再次调用reset()观察是否抛出InvalidMarkException
try {
buffer.reset();
System.out.println("\nclear()后reset()成功 - 这不应该发生!");
printBufferStatus(buffer);
} catch (InvalidMarkException e) {
System.out.println("\nclear()后reset()失败 (预期行为):");
System.out.println("抛出InvalidMarkException: " + e.getMessage());
System.out.println("原因: clear()方法会丢弃mark标记");
}
// 演示其他会使mark失效的操作
System.out.println("\n--- 演示其他使mark失效的场景 ---");
// 重新设置数据和标记
buffer.clear();
buffer.put(100).put(200);
buffer.mark(); // 在position=2处标记
buffer.put(300);
System.out.println("重新设置数据和标记后:");
printBufferStatus(buffer);
// 测试rewind()是否影响mark
buffer.rewind();
System.out.println("\n调用rewind()后:");
printBufferStatus(buffer);
try {
buffer.reset();
System.out.println("rewind()后reset()成功 - mark依然有效");
printBufferStatus(buffer);
} catch (InvalidMarkException e) {
System.out.println("rewind()后reset()失败: " + e.getMessage());
}
// 测试flip()是否影响mark
buffer.clear();
buffer.put(1000).put(2000);
buffer.mark(); // 标记
buffer.put(3000);
buffer.flip(); // 准备读取
System.out.println("\n调用flip()后:");
printBufferStatus(buffer);
try {
buffer.reset();
System.out.println("flip()后reset()成功");
printBufferStatus(buffer);
} catch (InvalidMarkException e) {
System.out.println("flip()后reset()失败: " + e.getMessage());
System.out.println("说明: flip()会丢弃mark标记");
}
}
// 打印缓冲区状态
private static void printBufferStatus(IntBuffer buffer) {
System.out.println("Position: " + buffer.position() +
", Limit: " + buffer.limit() +
", Capacity: " + buffer.capacity() +
", Remaining: " + buffer.remaining());
}
}

View File

@@ -0,0 +1,95 @@
import java.nio.CharBuffer;
public class BufferMarkReset {
public static void main(String[] args) {
// 创建一个容量为5的CharBuffer
CharBuffer buffer = CharBuffer.allocate(5);
System.out.println("初始状态:");
printBufferStatus(buffer);
// 写入字符A
buffer.put('A');
System.out.println("\n写入字符A后:");
printBufferStatus(buffer);
// 写入字符B
buffer.put('B');
System.out.println("\n写入字符B后:");
printBufferStatus(buffer);
// 在写入B后调用mark()方法此时position是2
buffer.mark();
System.out.println("\n调用mark()后 (position=2):");
printBufferStatus(buffer);
// 继续写入C、D、E直到缓冲区满
buffer.put('C');
buffer.put('D');
buffer.put('E');
System.out.println("\n继续写入C、D、E后:");
printBufferStatus(buffer);
// 调用reset()方法验证position是否回到标记位置
buffer.reset();
System.out.println("\n调用reset()后:");
printBufferStatus(buffer);
System.out.println("验证: position已回到标记位置 2");
// 从position 2开始重新读取并打印后续字符
// 首先需要调整limit以便能够读取
buffer.limit(5); // 设置limit为容量允许读取到末尾
System.out.println("\n从position 2开始读取后续字符:");
while (buffer.hasRemaining()) {
char c = buffer.get();
System.out.print("字符: " + c + " (position: " + buffer.position() + ")\n");
}
// 演示完整的读取过程
System.out.println("\n--- 完整演示 ---");
buffer.clear(); // 重置缓冲区
// 重新写入数据
buffer.put('A').put('B');
buffer.mark(); // 在position=2处标记
buffer.put('C').put('D').put('E');
// 切换到读模式
buffer.flip();
System.out.println("切换到读模式后:");
printBufferStatus(buffer);
// 读取所有数据以验证内容
System.out.println("完整内容:");
while (buffer.hasRemaining()) {
System.out.print(buffer.get() + " ");
}
System.out.println();
// 注意flip()方法会丢弃标记,所以需要重新设置
// 将position设置到想要标记的位置然后调用mark()
buffer.position(2); // 移动到位置2
buffer.mark(); // 重新标记
System.out.println("\n重新设置标记在position=2:");
printBufferStatus(buffer);
// 使用reset回到标记位置
buffer.reset();
System.out.println("\n使用reset()回到标记位置:");
printBufferStatus(buffer);
// 从标记位置开始读取
System.out.println("从标记位置开始读取:");
while (buffer.hasRemaining()) {
System.out.print(buffer.get() + " ");
}
System.out.println();
}
// 打印缓冲区状态
private static void printBufferStatus(CharBuffer buffer) {
System.out.println("Position: " + buffer.position() +
", Limit: " + buffer.limit() +
", Capacity: " + buffer.capacity() +
", Remaining: " + buffer.remaining());
}
}

View File

@@ -0,0 +1,163 @@
import java.nio.ByteBuffer;
public class BufferMarkerReader {
/**
* 使用ByteBuffer读取一段字节数据的方法
* 在读取到特定字节如0xFF时设置标记
* 继续读取后续字节直到遇到下一个0xFF
* 若未找到第二个0xFF则回退到标记位置
*
* @param buffer 要读取的ByteBuffer
* @param marker 标记字节默认为0xFF
* @return 读取的字节数组如果回退则返回null
*/
public static byte[] readWithMarker(ByteBuffer buffer, byte marker) {
if (!buffer.hasRemaining()) {
System.out.println("缓冲区没有剩余数据可读");
return null;
}
// 查找第一个标记字节
boolean firstMarkerFound = false;
int markPosition = -1;
// 寻找第一个0xFF
while (buffer.hasRemaining()) {
byte currentByte = buffer.get();
if (currentByte == marker) {
firstMarkerFound = true;
markPosition = buffer.position() - 1; // 标记字节的位置
buffer.mark(); // 在找到第一个标记后设置mark
System.out.println("找到第一个标记字节 0xFF位置: " + markPosition);
System.out.println("设置标记当前position: " + buffer.position());
break;
}
}
if (!firstMarkerFound) {
System.out.println("未找到第一个标记字节 0xFF");
return null;
}
// 收集从第一个标记到第二个标记之间的数据
ByteBuffer tempBuffer = ByteBuffer.allocate(buffer.remaining() + 1);
tempBuffer.put(marker); // 包含第一个标记字节
// 继续读取,寻找第二个标记字节
boolean secondMarkerFound = false;
while (buffer.hasRemaining()) {
byte currentByte = buffer.get();
tempBuffer.put(currentByte);
if (currentByte == marker) {
secondMarkerFound = true;
System.out.println("找到第二个标记字节 0xFF位置: " + (buffer.position() - 1));
break;
}
}
if (secondMarkerFound) {
// 找到第二个标记,返回两个标记之间的数据(包含标记字节)
tempBuffer.flip();
byte[] result = new byte[tempBuffer.remaining()];
tempBuffer.get(result);
System.out.println("成功读取数据,长度: " + result.length);
return result;
} else {
// 未找到第二个标记,回退到第一个标记位置
try {
buffer.reset();
System.out.println("未找到第二个标记字节,回退到标记位置");
System.out.println("回退后的position值: " + buffer.position());
return null;
} catch (Exception e) {
System.out.println("回退失败: " + e.getMessage());
return null;
}
}
}
public static void main(String[] args) {
// 测试用例1包含两个0xFF的数据
System.out.println("=== 测试用例1包含两个0xFF的数据 ===");
byte[] testData1 = {0x01, 0x02, (byte)0xFF, 0x03, 0x04, 0x05, (byte)0xFF, 0x06, 0x07};
ByteBuffer buffer1 = ByteBuffer.wrap(testData1);
System.out.println("原始数据:");
printByteArray(testData1);
System.out.println("初始buffer状态:");
printBufferStatus(buffer1);
byte[] result1 = readWithMarker(buffer1, (byte)0xFF);
if (result1 != null) {
System.out.println("读取结果:");
printByteArray(result1);
}
System.out.println("最终buffer状态:");
printBufferStatus(buffer1);
System.out.println("\n=== 测试用例2只有一个0xFF的数据 ===");
byte[] testData2 = {0x01, 0x02, (byte)0xFF, 0x03, 0x04, 0x05, 0x06};
ByteBuffer buffer2 = ByteBuffer.wrap(testData2);
System.out.println("原始数据:");
printByteArray(testData2);
System.out.println("初始buffer状态:");
printBufferStatus(buffer2);
byte[] result2 = readWithMarker(buffer2, (byte)0xFF);
if (result2 != null) {
System.out.println("读取结果:");
printByteArray(result2);
}
System.out.println("最终buffer状态:");
printBufferStatus(buffer2);
System.out.println("\n=== 测试用例3没有0xFF的数据 ===");
byte[] testData3 = {0x01, 0x02, 0x03, 0x04, 0x05};
ByteBuffer buffer3 = ByteBuffer.wrap(testData3);
System.out.println("原始数据:");
printByteArray(testData3);
byte[] result3 = readWithMarker(buffer3, (byte)0xFF);
if (result3 != null) {
System.out.println("读取结果:");
printByteArray(result3);
}
System.out.println("\n=== 测试用例4连续的0xFF ===");
byte[] testData4 = {0x01, (byte)0xFF, (byte)0xFF, 0x02, 0x03};
ByteBuffer buffer4 = ByteBuffer.wrap(testData4);
System.out.println("原始数据:");
printByteArray(testData4);
byte[] result4 = readWithMarker(buffer4, (byte)0xFF);
if (result4 != null) {
System.out.println("读取结果:");
printByteArray(result4);
}
}
// 辅助方法:打印字节数组
private static void printByteArray(byte[] array) {
System.out.print("[");
for (int i = 0; i < array.length; i++) {
System.out.printf("0x%02X", array[i]);
if (i < array.length - 1) {
System.out.print(", ");
}
}
System.out.println("]");
}
// 打印缓冲区状态
private static void printBufferStatus(ByteBuffer buffer) {
System.out.println("Position: " + buffer.position() +
", Limit: " + buffer.limit() +
", Capacity: " + buffer.capacity() +
", Remaining: " + buffer.remaining());
}
}

View File

@@ -0,0 +1,245 @@
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
public class BufferVerificationAndThinking {
public static void main(String[] args) {
// 1如何判断缓冲区是否还有剩余空间
testRemainingSpace();
System.out.println("\n" + "=".repeat(60));
// 2flip() 和 rewind() 的区别
testFlipVsRewind();
System.out.println("\n" + "=".repeat(60));
// 3直接缓冲区与非直接缓冲区的性能差异
testDirectVsNonDirectBuffer();
}
/**
* 1测试如何判断缓冲区是否还有剩余空间
*/
private static void testRemainingSpace() {
System.out.println("=== 1测试缓冲区剩余空间判断 ===");
ByteBuffer buffer = ByteBuffer.allocate(5);
System.out.println("创建容量为5的ByteBuffer:");
printBufferInfo(buffer);
// 写入数据测试剩余空间
System.out.println("\n逐步写入数据观察剩余空间变化:");
for (int i = 1; i <= 6; i++) {
if (buffer.hasRemaining()) {
buffer.put((byte) i);
System.out.println("写入字节 " + i + " 后:");
printBufferInfo(buffer);
} else {
System.out.println("尝试写入字节 " + i + ": 缓冲区已满,无法写入");
printBufferInfo(buffer);
break;
}
}
// 切换到读模式测试剩余数据
buffer.flip();
System.out.println("\n切换到读模式后:");
printBufferInfo(buffer);
System.out.println("\n逐步读取数据观察剩余数据变化:");
while (buffer.hasRemaining()) {
byte data = buffer.get();
System.out.println("读取字节 " + data + " 后:");
printBufferInfo(buffer);
}
if (!buffer.hasRemaining()) {
System.out.println("所有数据已读取完毕");
}
}
/**
* 2测试flip()和rewind()的区别
*/
private static void testFlipVsRewind() {
System.out.println("=== 2flip() 和 rewind() 的区别 ===");
CharBuffer buffer = CharBuffer.allocate(10);
// 写入一些数据
buffer.put("Hello");
System.out.println("写入'Hello'后的状态:");
printBufferInfo(buffer);
// 测试flip()
System.out.println("\n--- 测试flip()方法 ---");
CharBuffer buffer1 = buffer.duplicate(); // 创建副本用于测试
buffer1.flip();
System.out.println("调用flip()后:");
printBufferInfo(buffer1);
System.out.println("flip()的作用: position->0, limit->原position值, 准备从头读取已写入的数据");
// 读取数据验证flip的效果
System.out.println("使用flip()后读取数据:");
while (buffer1.hasRemaining()) {
System.out.print(buffer1.get());
}
System.out.println();
printBufferInfo(buffer1);
// 测试rewind()
System.out.println("\n--- 测试rewind()方法 ---");
CharBuffer buffer2 = buffer.duplicate(); // 创建副本用于测试
buffer2.rewind();
System.out.println("调用rewind()后:");
printBufferInfo(buffer2);
System.out.println("rewind()的作用: position->0, limit保持不变, 重新从头开始");
// 使用rewind后的缓冲区
System.out.println("使用rewind()后尝试读取数据 (limit仍为capacity):");
int readCount = 0;
while (buffer2.hasRemaining() && readCount < 5) { // 只读5个字符避免读取未初始化数据
char c = buffer2.get();
if (c != 0) { // 只打印非零字符
System.out.print(c);
}
readCount++;
}
System.out.println();
// 关键区别总结
System.out.println("\n--- 关键区别总结 ---");
System.out.println("flip(): position=0, limit=原position (准备读取已写入的数据)");
System.out.println("rewind(): position=0, limit=不变 (重新开始但limit通常是capacity)");
System.out.println("使用场景:");
System.out.println(" flip() - 写模式切换到读模式");
System.out.println(" rewind() - 重新读取整个缓冲区或重新写入");
}
/**
* 3测试直接缓冲区与非直接缓冲区的性能差异
*/
private static void testDirectVsNonDirectBuffer() {
System.out.println("=== 3直接缓冲区与非直接缓冲区的性能测试 ===");
int bufferSize = 1024 * 1024; // 1MB
int iterations = 1000;
// 创建直接缓冲区和非直接缓冲区
ByteBuffer directBuffer = ByteBuffer.allocateDirect(bufferSize);
ByteBuffer heapBuffer = ByteBuffer.allocate(bufferSize);
System.out.println("缓冲区大小: " + bufferSize + " 字节");
System.out.println("测试迭代次数: " + iterations);
System.out.println();
// 检查缓冲区类型
System.out.println("直接缓冲区检查: " + directBuffer.isDirect());
System.out.println("堆缓冲区检查: " + heapBuffer.isDirect());
System.out.println();
// 测试写入性能
System.out.println("--- 写入性能测试 ---");
// 测试直接缓冲区写入性能
long startTime = System.nanoTime();
for (int i = 0; i < iterations; i++) {
directBuffer.clear();
for (int j = 0; j < bufferSize; j++) {
directBuffer.put((byte) (j % 256));
}
}
long directWriteTime = System.nanoTime() - startTime;
// 测试堆缓冲区写入性能
startTime = System.nanoTime();
for (int i = 0; i < iterations; i++) {
heapBuffer.clear();
for (int j = 0; j < bufferSize; j++) {
heapBuffer.put((byte) (j % 256));
}
}
long heapWriteTime = System.nanoTime() - startTime;
System.out.println("直接缓冲区写入时间: " + (directWriteTime / 1_000_000) + " ms");
System.out.println("堆缓冲区写入时间: " + (heapWriteTime / 1_000_000) + " ms");
System.out.println("写入性能比: " + String.format("%.2f", (double) heapWriteTime / directWriteTime));
// 测试读取性能
System.out.println("\n--- 读取性能测试 ---");
// 准备数据
directBuffer.clear();
heapBuffer.clear();
for (int i = 0; i < bufferSize; i++) {
byte value = (byte) (i % 256);
directBuffer.put(value);
heapBuffer.put(value);
}
// 测试直接缓冲区读取性能
startTime = System.nanoTime();
for (int i = 0; i < iterations; i++) {
directBuffer.flip();
while (directBuffer.hasRemaining()) {
directBuffer.get();
}
directBuffer.rewind();
}
long directReadTime = System.nanoTime() - startTime;
// 测试堆缓冲区读取性能
startTime = System.nanoTime();
for (int i = 0; i < iterations; i++) {
heapBuffer.flip();
while (heapBuffer.hasRemaining()) {
heapBuffer.get();
}
heapBuffer.rewind();
}
long heapReadTime = System.nanoTime() - startTime;
System.out.println("直接缓冲区读取时间: " + (directReadTime / 1_000_000) + " ms");
System.out.println("堆缓冲区读取时间: " + (heapReadTime / 1_000_000) + " ms");
System.out.println("读取性能比: " + String.format("%.2f", (double) heapReadTime / directReadTime));
// 性能差异原因分析
System.out.println("\n--- 性能差异原因分析 ---");
System.out.println("1. 内存分配位置:");
System.out.println(" 直接缓冲区: 分配在JVM堆外的本地内存中");
System.out.println(" 非直接缓冲区: 分配在JVM堆内存中");
System.out.println("\n2. I/O操作效率:");
System.out.println(" 直接缓冲区: 减少一次内存拷贝 (本地内存 -> 系统调用)");
System.out.println(" 非直接缓冲区: 需要额外拷贝 (JVM堆 -> 本地内存 -> 系统调用)");
System.out.println("\n3. 垃圾回收影响:");
System.out.println(" 直接缓冲区: 不受GC直接影响但清理较复杂");
System.out.println(" 非直接缓冲区: 受GC影响但分配和释放更快");
System.out.println("\n4. 使用建议:");
System.out.println(" 直接缓冲区: 适用于长期存在、频繁I/O操作的大缓冲区");
System.out.println(" 非直接缓冲区: 适用于短期、小规模的内存操作");
// 内存使用情况
System.out.println("\n--- 内存使用情况 ---");
Runtime runtime = Runtime.getRuntime();
System.out.println("JVM堆内存使用情况:");
System.out.println(" 最大内存: " + (runtime.maxMemory() / 1024 / 1024) + " MB");
System.out.println(" 总内存: " + (runtime.totalMemory() / 1024 / 1024) + " MB");
System.out.println(" 空闲内存: " + (runtime.freeMemory() / 1024 / 1024) + " MB");
System.out.println(" 已用内存: " + ((runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024) + " MB");
}
/**
* 打印缓冲区详细信息
*/
private static void printBufferInfo(java.nio.Buffer buffer) {
System.out.println(" Position: " + buffer.position() +
" | Limit: " + buffer.limit() +
" | Capacity: " + buffer.capacity() +
" | Remaining: " + buffer.remaining() +
" | HasRemaining: " + buffer.hasRemaining());
}
}

View File

@@ -0,0 +1,142 @@
import java.util.concurrent.locks.ReentrantLock;
public class TicketSystem {
private int ticketCount = 100; // 初始票数
private final ReentrantLock lock = new ReentrantLock(); // 可重入锁
private int totalSold = 0; // 已售票数统计
/**
* 卖票方法 - 线程安全
*
* @param sellerId 售票员ID
* @return true表示成功卖出一张票false表示没有票了
*/
public boolean sellTicket(String sellerId) {
lock.lock(); // 获取锁
try {
if (ticketCount > 0) {
// 模拟卖票过程的耗时
try {
Thread.sleep(10); // 模拟卖票耗时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
ticketCount--;
totalSold++;
int currentTicket = 100 - ticketCount; // 当前卖出的是第几张票
System.out.println(sellerId + " 卖出第 " + currentTicket + " 张票,剩余票数: " + ticketCount);
return true;
} else {
System.out.println(sellerId + " 尝试卖票,但已无票可售");
return false;
}
} finally {
lock.unlock(); // 确保锁被释放
}
}
/**
* 获取剩余票数
*/
public int getRemainingTickets() {
lock.lock();
try {
return ticketCount;
} finally {
lock.unlock();
}
}
/**
* 获取已售票数
*/
public int getTotalSold() {
lock.lock();
try {
return totalSold;
} finally {
lock.unlock();
}
}
/**
* 售票员线程类
*/
static class TicketSeller implements Runnable {
private final TicketSystem ticketSystem;
private final String sellerId;
public TicketSeller(TicketSystem ticketSystem, String sellerId) {
this.ticketSystem = ticketSystem;
this.sellerId = sellerId;
}
@Override
public void run() {
System.out.println(sellerId + " 开始售票");
while (true) {
boolean sold = ticketSystem.sellTicket(sellerId);
if (!sold) {
// 没有票了,结束售票
break;
}
// 模拟售票间隔
try {
Thread.sleep(20);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
System.out.println(sellerId + " 结束售票");
}
}
public static void main(String[] args) {
TicketSystem ticketSystem = new TicketSystem();
System.out.println("=== 卖票系统启动 ===");
System.out.println("初始票数: " + ticketSystem.getRemainingTickets());
// 创建3个售票员线程
Thread seller1 = new Thread(new TicketSeller(ticketSystem, "售票员1"));
Thread seller2 = new Thread(new TicketSeller(ticketSystem, "售票员2"));
Thread seller3 = new Thread(new TicketSeller(ticketSystem, "售票员3"));
// 启动线程
long startTime = System.currentTimeMillis();
seller1.start();
seller2.start();
seller3.start();
// 等待所有线程结束
try {
seller1.join();
seller2.join();
seller3.join();
} catch (InterruptedException e) {
System.out.println("主线程被中断");
}
long endTime = System.currentTimeMillis();
// 输出最终结果
System.out.println("\n=== 售票结束 ===");
System.out.println("剩余票数: " + ticketSystem.getRemainingTickets());
System.out.println("已售票数: " + ticketSystem.getTotalSold());
System.out.println("总耗时: " + (endTime - startTime) + " 毫秒");
// 验证结果
if (ticketSystem.getRemainingTickets() == 0 && ticketSystem.getTotalSold() == 100) {
System.out.println("✓ 验证成功:所有票都已售出,且没有重复售票");
} else {
System.out.println("✗ 验证失败:票数统计有误");
}
}
}

29
NIOChatServ/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

10
NIOChatServ/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 依赖于环境的 Maven 主目录路径
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
NIOChatServ/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
NIOChatServ/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/NIOChatServ.iml" filepath="$PROJECT_DIR$/NIOChatServ.iml" />
</modules>
</component>
</project>

4
NIOChatServ/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,255 @@
package client;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
public class NioChatClient extends JFrame {
// UI 组件
private JTextField hostField;
private JTextField portField;
private JButton connectButton;
private JTextArea messageArea; // 显示聊天内容
private JTextField inputField; // 输入框
private JButton sendButton; // 发送按钮
// NIO相关
private volatile SocketChannel socketChannel;
private volatile Selector selector;
private volatile boolean running = false; // 用于控制读线程
private Thread readThread; // 后台读取服务器消息的线程
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
NioChatClient client = new NioChatClient();
client.setVisible(true);
});
}
/**
* 构造UI
*/
public NioChatClient() {
super("NIO Chat Client");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
// 主机、端口输入区域
JPanel connectPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
connectPanel.add(new JLabel("服务器主机:"));
hostField = new JTextField("127.0.0.1", 10);
connectPanel.add(hostField);
connectPanel.add(new JLabel("端口:"));
portField = new JTextField("8888", 5);
connectPanel.add(portField);
connectButton = new JButton("连接");
connectPanel.add(connectButton);
// 聊天显示区域
messageArea = new JTextArea();
messageArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(messageArea);
// 发送消息区域
JPanel inputPanel = new JPanel(new BorderLayout());
inputField = new JTextField();
sendButton = new JButton("发送");
inputPanel.add(inputField, BorderLayout.CENTER);
inputPanel.add(sendButton, BorderLayout.EAST);
// 布局
getContentPane().setLayout(new BorderLayout());
getContentPane().add(connectPanel, BorderLayout.NORTH);
getContentPane().add(scrollPane, BorderLayout.CENTER);
getContentPane().add(inputPanel, BorderLayout.SOUTH);
// 按钮事件绑定
connectButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!running) {
connectToServer();
} else {
disconnectFromServer();
}
}
});
sendButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sendMessage(inputField.getText().trim());
inputField.setText("");
}
});
}
/**
* 连接到服务器
*/
private void connectToServer() {
final String host = hostField.getText().trim();
final int port = Integer.parseInt(portField.getText().trim());
try {
// 打开Selector和SocketChannel
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(host, port));
socketChannel.register(selector, SelectionKey.OP_CONNECT);
// 启动后台线程,处理服务器消息
running = true;
readThread = new Thread(this::readLoop, "NioClient-ReadThread");
readThread.start();
// 更新UI状态
connectButton.setText("断开");
appendMessage("正在连接到服务器 " + host + ":" + port + "...\n");
} catch (IOException e) {
appendMessage("连接失败: " + e.getMessage() + "\n");
e.printStackTrace();
}
}
/**
* 断开与服务器的连接
*/
private void disconnectFromServer() {
running = false;
try {
if (socketChannel != null) {
socketChannel.close();
}
if (selector != null) {
selector.wakeup();
selector.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
socketChannel = null;
selector = null;
connectButton.setText("连接");
appendMessage("已断开连接。\n");
}
}
/**
* 发送消息给服务器
*/
private void sendMessage(String msg) {
if (!running || socketChannel == null || !socketChannel.isOpen()) {
appendMessage("未连接服务器,无法发送消息。\n");
return;
}
if (msg.isEmpty()) {
return;
}
try {
socketChannel.write(ByteBuffer.wrap((msg + "\n").getBytes()));
} catch (IOException e) {
appendMessage("发送失败: " + e.getMessage() + "\n");
e.printStackTrace();
}
}
/**
* 读取服务器消息的循环线程
*/
private void readLoop() {
try {
while (running && selector != null && selector.isOpen()) {
// 阻塞等待事件
selector.select();
// 处理所有就绪事件
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (!key.isValid()) {
continue;
}
// 处理连接完成
if (key.isConnectable()) {
handleConnect(key);
}
// 处理可读
if (key.isReadable()) {
handleRead(key);
}
}
}
} catch (IOException e) {
appendMessage("读取服务器消息时出现异常: " + e.getMessage() + "\n");
e.printStackTrace();
} finally {
// 读线程结束时进行清理
disconnectFromServer();
}
}
/**
* 处理连接完成
*/
private void handleConnect(SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
if (sc.isConnectionPending()) {
sc.finishConnect();
}
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
appendMessage("已连接到服务器。\n");
}
/**
* 处理可读事件:从服务器接收数据
*/
private void handleRead(SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int readBytes = sc.read(buffer);
if (readBytes == -1) {
// 服务器端关闭
appendMessage("服务器已断开连接。\n");
running = false;
return;
}
if (readBytes > 0) {
buffer.flip();
// 按照简单文本协议,读到换行符即可作为一条消息
String msg = new String(buffer.array(), 0, buffer.limit()).trim();
appendMessage(msg + "\n");
}
}
/**
* 在UI文本框中追加消息 (线程安全)
*/
private void appendMessage(String msg) {
SwingUtilities.invokeLater(() -> {
messageArea.append(msg);
// 自动滚动到末尾
messageArea.setCaretPosition(messageArea.getDocument().getLength());
});
}
}

View File

@@ -0,0 +1,153 @@
package server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class NioChatServer {
// 维护所有已连接的 SocketChannel
private static final ConcurrentHashMap<SocketChannel, String> clientMap = new ConcurrentHashMap<>();
public static void main(String[] args) {
// 端口可根据需要进行修改
int port = 8888;
try (Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
// 配置为非阻塞
serverSocketChannel.configureBlocking(false);
// 绑定端口
serverSocketChannel.bind(new InetSocketAddress(port));
// 注册到 selector监听 "接收新连接" 事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务器已启动,监听端口: " + port);
// 事件循环
while (true) {
// 阻塞等待就绪的通道
selector.select();
// 获取就绪的事件集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove(); // 每次处理完一个事件后必须移除,避免重复处理
try {
// 处理新连接
if (key.isAcceptable()) {
handleAccept(key, selector);
}
// 处理可读事件
if (key.isReadable()) {
handleRead(key, selector);
}
} catch (IOException e) {
// 发生异常时关闭连接并清理
closeChannel(key);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 处理新客户端连接
*/
private static void handleAccept(SelectionKey key, Selector selector) throws IOException {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
if (sc == null) {
return;
}
// 配置为非阻塞
sc.configureBlocking(false);
// 注册到选择器中,关注读事件
sc.register(selector, SelectionKey.OP_READ);
// 将此客户端加入管理集合(如果需要,可以存储客户端的名称/ID等信息)
clientMap.put(sc, sc.getRemoteAddress().toString());
System.out.println("客户端连接: " + sc.getRemoteAddress());
}
/**
* 处理客户端发送的数据
*/
private static void handleRead(SelectionKey key, Selector selector) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int readBytes = sc.read(buffer);
// 正常关闭或异常
if (readBytes == -1) {
closeChannel(key);
return;
}
// 如果有数据
if (readBytes > 0) {
buffer.flip();
String msg = new String(buffer.array(), 0, buffer.limit()).trim();
System.out.println("收到消息: " + msg + " 来自: " + clientMap.get(sc));
// 识别特殊命令
if ("EXIT".equalsIgnoreCase(msg)) {
// 关闭连接
System.out.println("客户端请求断开连接: " + clientMap.get(sc));
closeChannel(key);
} else if ("PING".equalsIgnoreCase(msg)) {
// 回复 PONG
String pong = "PONG\n";
sc.write(ByteBuffer.wrap(pong.getBytes()));
} else {
// 普通消息进行广播
broadcastMessage(sc, msg);
}
}
}
/**
* 向其他所有客户端广播消息
*/
private static void broadcastMessage(SocketChannel sender, String msg) {
// 构造广播内容
String senderInfo = clientMap.get(sender);
String broadcastMsg = "[" + senderInfo + "] " + msg + "\n";
// 遍历所有连接的客户端, 写入消息
clientMap.forEach((channel, info) -> {
if (channel != sender && channel.isOpen()) {
try {
channel.write(ByteBuffer.wrap(broadcastMsg.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
/**
* 关闭通道,清理资源
*/
private static void closeChannel(SelectionKey key) {
try {
SocketChannel sc = (SocketChannel) key.channel();
System.out.println("连接关闭: " + clientMap.get(sc));
clientMap.remove(sc);
key.cancel();
sc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

29
example_src/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
example_src/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

5
example_src/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
example_src/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Network_Communication.iml" filepath="$PROJECT_DIR$/Network_Communication.iml" />
</modules>
</component>
</project>

4
example_src/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

24
example_src/src/Bus.java Normal file
View File

@@ -0,0 +1,24 @@
public class Bus implements MyPay,MyInterface2 {
public void payMoney() {
System.out.println("Bus pay money:2元");
}
public void myPrint() {
System.out.println("my bus print");
}
public void myMethod() {
System.out.println("aggdksjal");
}
@Override
public void MyInter1Fun() {
}
@Override
public void MyInter2Fun() {
}
}

View File

@@ -0,0 +1,18 @@
class MyClass1{
int a1;
int a2;
void myPrint(){
System.out.println("a1 = " + a1);
}
}
class MyClass2 {
int a3;
void myPrint(){
System.out.println("a3 = " + a3);
}
}
public class MyDemo1 extends MyClass1{
}

View File

@@ -0,0 +1,3 @@
public interface MyInterface2 {
public void myMethod();
}

View File

@@ -0,0 +1,13 @@
interface MyInter1{
void MyInter1Fun();
}
interface MyInter2{
void MyInter2Fun();
}
public interface MyPay extends MyInter1, MyInter2 {
// int x=9;
void payMoney();
void myPrint();
}

View File

@@ -0,0 +1,23 @@
public class MyTest1 {
public static void main(String[] args) {
int a=0;
int y=100;
int z;
try{
z=y/a;
} catch (ArithmeticException e) {
System.out.println("ArithmeticException");
z=Integer.MAX_VALUE;
System.out.println(z);
}
catch (Exception e) {
System.out.println("Exception");
}
}
}

View File

@@ -0,0 +1,32 @@
public class Test1 implements Runnable {
public static void main(String[] args) throws InterruptedException {
System.out.println("Hello World");
Test1 t = new Test1();
Thread th1=new Thread(t);
th1.setName("Thread1");
//th1.run();
th1.start();
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("in main");
}
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// throw new RuntimeException(e);
}
System.out.println("nantongdaxue");
System.out.println(Thread.currentThread().getName());
}
}
}

View File

@@ -0,0 +1,14 @@
public class Test2 {
public static void main(String[] args) {
int a = 0;
int y;
try{
y=3/a;
}catch(ArithmeticException e){
System.out.println("ArithmeticException");
y=Integer.MAX_VALUE;
}
System.out.println(y);
}
}

View File

@@ -0,0 +1,39 @@
class MyThread extends Thread{
public void run(){
for(int i=0;i<10;i++){
try {
Thread.sleep(1000);
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
System.out.println("in myThread:"+Thread.currentThread().getName());
}
}
}
public class Test3 {
public static void main(String[] args) throws InterruptedException {
MyThread t1=new MyThread();
t1.setName("t1");
t1.start();
MyThread t2=new MyThread();
t2.setName("t2");
t2.start();
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("in main:"+Thread.currentThread().getName());
}
}
}

View File

@@ -0,0 +1,21 @@
package abc;
public class C1 extends Thread{
private char ch;
private PrintCH pc;
public C1(char ch, PrintCH pc) {
this.ch = ch; this.pc=pc;
}
public void run(){
pc.print(ch);
}
public static void main(String[] args) {
PrintCH pc1=new PrintCH();
PrintCH pc2=new PrintCH();
C1 t1=new C1('A',pc2);
C1 t2=new C1('B',pc2);
t1.start();
t2.start();
}
}

View File

@@ -0,0 +1,14 @@
package abc;
public class PrintCH {
public synchronized void print(char c){
for(int i=0;i<4;i++){
System.out.print(c);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="17" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,18 @@
package demo1;
public class MainTest {
public static void main(String[] args) {
MyThread1 t1 = new MyThread1();
Thread myt1 = new Thread(t1);
myt1.start();
MyThread2 t2 = new MyThread2();
t2.start();
System.out.println("this is a main function");
}
}

View File

@@ -0,0 +1,19 @@
package demo1;
public class MyThread1 implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("this is a car");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -0,0 +1,16 @@
package demo1;
public class MyThread2 extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("this is a bus");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="17" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,5 @@
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

View File

@@ -0,0 +1,22 @@
package pk1;
public class MyTest extends Thread{
private char ch;
private PrintCH2 myprint;
public MyTest(char ch, PrintCH2 myprint){
this.ch = ch;
this.myprint = myprint;
}
public void run(){
synchronized(myprint){
myprint.print(ch);
}
myprint.print(ch);
}
public static void main(String[] args){
PrintCH2 printch2 = new PrintCH2();
MyTest t1 = new MyTest('A', myprint);
MyTest t2 = new MyTest('B', myprint);
t1.start();
t2.start();
}
}

View File

@@ -0,0 +1,49 @@
package pk1.pk2;
class Thread3 implements Runnable {
public void run(){
System.out.println("in thread3");
}
}
class MyThread2 extends Thread {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("in MyThread2"+Thread.currentThread().getName());
}
}
}
public class MyThread1 {
public static void main(String[] args) throws InterruptedException {
MyThread2 t = new MyThread2();
t.setName("Thread2");
t.start();
Thread t2 = new Thread(t);
t2.setName("Thread3");
t2.start();
System.out.println(t2.isAlive());
System.out.println(t.isAlive());
Thread3 th3 = new Thread3();
Thread myth3 = new Thread(th3);
myth3.setName("MyThread3");
myth3.start();
// Thread myth6 = new Thread("aba");
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("nantongdaxue");
}
}
}

29
onetoone/.gitignore vendored Normal file
View File

@@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

10
onetoone/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 依赖于环境的 Maven 主目录路径
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

5
onetoone/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
onetoone/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/onetoone.iml" filepath="$PROJECT_DIR$/onetoone.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="MyClient" type="Application" factoryName="Application" singleton="false" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="MyClient" />
<module name="onetoone" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -0,0 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="MyServer" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="MyServer" />
<module name="onetoone" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

Some files were not shown because too many files have changed in this diff Show More