1,线程通信的概念:

多线程通过共享数据和线程相关API对线程执行过程一定的控制。

2,为什么要使用线程通信:

多个线程并发执行时,在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们希望他们有规律的执行,那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作共享数据

3,等待与唤醒的方法:(Object类中)

  1. 对应使用:同步代码块和锁对象;

(这些方法都要使用锁对象在同步代码块中调用),且需要2个或以上的线程;
image.png
注意:notify是唤醒另一个线程;

4,使用:

  1. public class Text01 {
  2. public static void main(String[] args) {
  3. ArrayList<String> list = new ArrayList<>();
  4. //生产者
  5. new Thread(new Runnable() {
  6. @Override
  7. public void run() {
  8. int number = 1;
  9. while (true) {
  10. //使用同步代码块用list集合对象作为锁;
  11. synchronized (list) {
  12. if (list.size() > 0) {
  13. //唤醒另一个线程(消费者)
  14. list.notify();
  15. try {
  16. //休眠
  17. list.wait();
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. }else {
  22. //设置延迟,延缓输出
  23. try {
  24. Thread.sleep(100);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. //添加到集合
  29. list.add("包子"+number);
  30. number++;
  31. System.out.println("厨师生产了:"+list);
  32. //唤醒消费者
  33. list.notify();
  34. }
  35. }
  36. }
  37. }
  38. }).start();
  39. //消费者
  40. new Thread(new Runnable() {
  41. @Override
  42. public void run() {
  43. while (true) {
  44. //使用同步代码块并使用list集合对象作为锁
  45. synchronized (list) {
  46. if (list.size()==0) {
  47. //唤醒生产者
  48. list.notify();
  49. try {
  50. list.wait();
  51. } catch (InterruptedException e) {
  52. e.printStackTrace();
  53. }
  54. }else {
  55. //移除
  56. String remove = list.remove(0);
  57. System.out.println("吃货吃掉了:"+remove);
  58. //吃完了,然后唤醒生产者
  59. list.notify();
  60. }
  61. }
  62. }
  63. }
  64. }).start();
  65. }
  66. }