/**
使用的对象
/
class Romm{
private int count =0;
public void increment(){
synchronized (this){
count++;
}
}
public void decrement(){
synchronized (this){
count--;
}
}
//取值也得上锁,防止increment和decrement没有执行完毕就取值,
public int getCount(){
synchronized (this){
return count;
}
}
}
public static void main(String[] args) throws InterruptedException {
/**
两个线程,一个自加一个自减
/
Thread t3 = new Thread(() -> {
for (int i = 0; i < 50000000; i++) {
romm.increment();
}
});
Thread t4 = new Thread(() -> {
for (int i = 0; i < 50000000; i++) {
romm.decrement();
}
});
t3.start();
t4.start();
//确保t3,t4线程进入运行态
Thread.sleep(200);
int count = romm.getCount();
log.debug("count:{}",count); //17:42:46.237 [main] DEBUG c.SynchronizedTest - count:250137
}
count难道不应该是50000000或者-50000000或者0吗? 主线程执行romm.getCount()时,不会被阻塞吗?因为锁已经被t3,t4其中一个占用了,当t3,t4其中一个使用完毕,主线程和其中一个线程去抢占锁,最后结果不是50000000或者-50000000或者0吗?
线程同步实质上是一个等待机制。线程同步时会将多个线程放入对象等待池中进行排队(队列),等待前一个线程执行操作完毕,再有下一个线程进行执行操作。每个对象都有一个独有的锁(排他锁),每个线程执行时都会获得对象的排他锁,这样只有获得锁的线程可以对对象进行操作,执行结束后排他锁被下一个线程获得。总结来说,线程同步的形成条件就是:队列+锁。
你所谓的占用是在每一轮循环中占用,循环完毕就释放锁了,别的线程就可以调用变量了,所以最终是3个线程在竞争,没有那个线程能独占
volatile是否需要加一下呢?