Java多线程并发问题:同步锁和死锁示例
在Java编程中,多线程并发会遇到各种问题,包括同步锁、死锁等。下面通过实例来解释这两种情况。
同步锁:
当一个线程访问共享资源时,通常需要使用某种形式的锁(如synchronized关键字)来保护共享资源不被其他线程同时访问。示例代码:
// 假设我们有一个共享对象count
private int count = 0;
public synchronized void increment() {
count++;
notifyAll(); // 线程等待唤醒后继续执行
}
public synchronized void decrement() {
if (count > 0) {
count--;
notifyAll();
}
}
public static void main(String[] args) {
MyCounter counter = new MyCounter();
// 创建两个线程并发操作counter
Thread incrementThread = new Thread(() -> {
while (!counter.increment()) { // 线程等待锁
try {
// 线程休眠一段时间以避免CPU浪费
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}));
Thread decrementThread = new Thread(() -> {
while (!counter.decrement())) { // 线程等待锁
try {
// 同理,线程休眠以避免CPU浪费
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}));
incrementThread.start();
decrementThread.start();
// 等待两个线程执行完毕后打印结果
try {
incrementThread.join(); // 线程等待
decrementThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终计数: " + counter.getCount());
}
在上述代码中,我们创建了一个共享的计数器count
。两个线程分别执行increment
和decrement
操作。通过使用synchronized
关键字来确保线程安全。
死锁:
当两个或多个线程因争夺资源而造成的一种互相等待的现象时,就会发生死锁。示例代码(有死锁风险):
// 假设我们有一个共享对象count
private int count = 0;
public synchronized void increment() {
if (count < 10) { // 确保计数不会超过10,否则会出现死锁
count++;
notifyAll();
} else {
System.out.println("错误:尝试将计数器提升到10以上,但资源已耗尽。");
}
}
public static void main(String[] args) {
MyCounter counter = new MyCounter();
// 创建两个线程并发操作counter
Thread incrementThread = new Thread(() -> {
while (!counter.increment())) { // 线程等待锁
try {
// 线程休眠一段时间以避免CPU浪费
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}));
Thread decrementThread = new Thread(() -> {
while (!counter.decrement())) { // 线程等待锁
try {
// 同理,线程休眠以避免CPU浪费
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}));
incrementThread.start();
decrementThread.start();
// 等待两个线程执行完毕后打印结果
try {
incrementThread.join(); // 线程等待
decrementThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终计数: " + counter.getCount());
}
在这个示例中,我们创建了两个线程分别执行increment
和decrement
操作。但是,我们在increment
方法中添加了一个条件判断:如果计数器值超过10,就会抛出一个错误并停止计数。这种情况下,线程会一直等待直到计数器被正确释放。
这就是死锁的一种情况,当资源分配不均衡且循环等待时,就可能导致死锁。
还没有评论,来说两句吧...