Java多线程要点

使用synchronized锁实现线程同步

为了避免多线程在共享资源时发生冲突,所以要在线程使用该资源时,就为资源上一把“锁”。第1个访问资源的线程为资源上锁,其他线程若想访问该资源,则必须等到解锁最为止。解锁的同时,另一个线程访问资源并为资源上锁。就像平时吃饭一样,锅里只有一把饭勺,一次只允许一个人盛饭,而这个饭勺就是共享资源,来盛饭的人就像是一个个线程。

  • 同步代码块
  • 同步方法

Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解

Java多线程——使用synchronized锁实现线程同步

线程间的沟通,使用notify(),notifyAll()和wait()方法。

wait(),notify(),notifyAll()及sleep() 和wait()的区别

调用wait()、 notify()以及notifyAll()时需要注意的细节, 如下。
1) 使用wait()、notify()和notifyAll()时需要先对调用对象加锁。
2) 调用wait()方法后, 线程状态由 RUNNING变为WAITING, 并将当前线程放置到对象的
等待队列。
3) notify()或notifyAll()方法调用后, 等待线程依旧不会从wait()返回, 需要调用notify()或
notifAll()的线程释放锁之后, 等待线程才有机会从wait()返回。
4) notify()方法将等待队列中的一个等待线程从等待队列中移到同步队列中, 而notifyAll()
方法则是将等待队列中所有的线程全部移到同步队列, 被移动的线程状态由 WAITING变为
BLOCKED。
5) 从wait()方法返回的前提是获得了调用对象的锁。
6)要注意的一点就是执行nitifyAll()方法时不会立刻就释放对象的锁,而是要等到线程执行完成后才会释放但是执行wait()方法时就是会立刻释放对象的锁,然后当前线程就会卡在wait()方法处,等待唤醒。另外还有一点需要提的是这三个方法都必须被包裹在同步块中。

wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能。因为都个对像都有锁,锁是每个对像的基础,当然操作锁的方法也是最基础了。

wait():

等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。

调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。

notify():

唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

notifyAll():

唤醒所有等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。
参考https://blog.csdn.net/wangjun_818/article/details/77649198

猜你喜欢

转载自blog.csdn.net/qq_40629792/article/details/85222002
今日推荐