Java多线程并发问题解决示例
在Java编程中,多线程并发是一个常见且重要的问题。以下是一些问题及解决示例:
竞态条件(Race Conditions):多个线程同时访问和修改共享资源,可能会导致不期望的结果。
解决示例:
// 假设一个计数器
AtomicInteger counter = new AtomicInteger(0);
// 创建两个线程
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
// 尝试增加计数器
if (counter.incrementAndGet() == 10) {
System.out.println("Thread 1 successfully incremented counter.");
break;
}
}
// 确保线程正常退出
thread1.join();
}));
Thread thread2 = new Thread(() -> {
for (int i = 5; i < 10; i++) {
// 尝试减小计数器
if (counter.decrementAndGet() == 0) {
System.out.println("Thread 2 successfully decremented counter.");
break;
}
}
// 确保线程正常退出
thread2.join();
}));
// 启动两个线程
thread1.start();
thread2.start();
// 等待所有线程完成
try {
Thread.sleep(1000); // 假设线程需要一定时间来执行
} catch (InterruptedException e) {
e.printStackTrace();
}
死锁(Deadlocks):当两个或多个线程互相等待对方释放资源时,就可能发生死锁。
解决示例:
// 假设一个银行账户和两个存款操作
class BankAccount {
int balance = 0;
// 存款操作1
void deposit1(int amount) {
if (amount > 0 && balance + amount < Integer.MAX_VALUE)) {
balance += amount;
System.out.println("Deposit 1 successful. New balance: " + balance);
} else {
System.out.println("Deposit 1 failed. Invalid amount or balance limit exceeded.");
}
}
// 存款操作2
void deposit2(int amount) {
if (amount > 0 && balance + amount < Integer.MAX_VALUE)) {
balance += amount;
System.out.println("Deposit 2 successful. New balance: " + balance);
} else {
System.out.println("Deposit 2 failed. Invalid amount or balance limit exceeded.");
}
}
// 撤销存款操作1
void withdraw1(int amount) {
if (amount > 0 && balance - amount >= 0)) {
balance -= amount;
System.out.println("Withdraw 1 successful. New balance: " + balance);
} else {
System.out.println("Withdraw 1 failed. Invalid amount or insufficient balance.");
}
}
// 撤销存款操作2
void withdraw2(int amount) {
if (amount > 0 && balance - amount >= 0)) {
balance -= amount;
System.out.println("Withdraw 2 successful. New balance: " + balance);
} else {
System.out.println("Withdraw 2 failed. Invalid amount or insufficient balance.");
}
}
}
public class Main {
public static void main(String[] args) {
// 创建一个银行账户实例
BankAccount bankAccount = new BankAccount();
// 调用存款操作1和2,模拟两个线程同时进行存款操作
bankAccount.deposit1(500);
bankAccount.deposit2(300);
// 线程1模拟完成存款操作后,再尝试撤销存款操作1
Thread thread1 = new Thread(() -> {
bankAccount.withdraw1(500); // 模拟撤销存款操作1
System.out.println("Thread 1 successfully attempted to cancel deposit 1.");
}));
// 线程2模拟完成存款操作后,再尝试撤销存款操作2
Thread thread2 = new Thread(() -> {
bankAccount.withdraw2(300); // 模拟撤销存款操作2
System.out.println("Thread 2 successfully attempted to cancel deposit 2.");
}));
// 启动两个线程
thread1.start();
thread2.start();
// 等待所有线程完成
try {
Thread.sleep(1000); // 假设线程需要一定时间来执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final balance: " + bankAccount.balance); // 检查最终余额是否正确
}
}
}
这个示例模拟了两个线程(Thread 1 和 Thread 2)同时执行存款操作,然后一个线程尝试撤销存款。这样就避免了死锁的发生,并展示了如何解决并发问题。
还没有评论,来说两句吧...