Java多线程实践:同步代码块案例对比
在Java多线程编程中,同步代码块是一种常用的互斥机制。这里我们将通过一个案例对比来阐述这一点。
案例一:无同步的线程操作
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
// 多个线程同时访问Counter实例
Thread t1 = new Thread(() -> {
Counter counter = new Counter();
for (int i = 0; i < 5; i++) {
counter.increment(); // 直接操作,无同步保护
}
}));
Thread t2 = new Thread(() -> {
Counter counter = new Counter();
for (int i = 0; i < 5; i++) {
counter.getCount(); // 不直接修改值,但读取时未同步保护
}
});
t1.start();
t2.start();
在这个案例中,线程t1
和t2
同时访问同一个Counter
实例。由于没有同步代码块进行保护,结果是不可预知的。
案例二:使用synchronized关键字的同步代码块
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
notifyAll(); // 发送通知,等待线程重新进入方法
}
public synchronized int getCount() {
while (count == 0) { // 确保计数器值不为0
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return count;
}
}
// 多个线程同时访问Counter实例
Thread t1 = new Thread(() -> {
Counter counter = new Counter();
for (int i = 0; i < 5; i++) {
counter.increment(); // 同步代码块保护,确保结果正确
}
});
Thread t2 = new Thread(() -> {
Counter counter = new Counter();
for (int i = 0; i < 5; i++) {
counter.getCount(); // 同样,同步代码块确保读取的值是正确的
}
});
t1.start();
t2.start();
在案例二中,我们为increment()
和getCount()
方法添加了synchronized
关键字,这使得它们在同一时间只能被一个线程访问。
这样做的结果就是无论多个线程同时对同一个实例进行操作,都能够保证数据的完整性和一致性。
还没有评论,来说两句吧...