线程间通信的模型有两种:共享内存和消息传递

  • 以下方式都是基本这两种模 型来实现的。我们来基本一道面试常见的题目来分析 场景—-两个线程,一个线程对当前数值加 1,另一个线程对当前数值减 1,要求 用线程间通信

synchronized方案

  1. public class TestVolatile {
  2. /**
  3. * 交替加减
  4. * @param args
  5. */
  6. public static void main(String[] args){
  7. DemoClass demoClass = new DemoClass();
  8. new Thread(() ->{
  9. for (int i = 0; i < 5; i++) {
  10. demoClass.increment();
  11. }
  12. }, "线程 A").start();
  13. new Thread(() ->{
  14. for (int i = 0; i < 5; i++) {
  15. demoClass.decrement();
  16. }
  17. }, "线程 B").start();
  18. }
  19. }
  20. package com.atguigu.test;
  21. class DemoClass{
  22. //加减对象
  23. private int number = 0;
  24. /**
  25. * 加 1
  26. */
  27. public synchronized void increment() {
  28. try {
  29. while (number != 0){
  30. this.wait();
  31. }
  32. number++;
  33. System.out.println("--------" + Thread.currentThread().getName() + "加一成
  34. 功----------,值为:" + number);
  35. notifyAll();
  36. }catch (Exception e){
  37. e.printStackTrace();
  38. }
  39. }
  40. /**
  41. * 减一
  42. */
  43. public synchronized void decrement(){
  44. try {
  45. while (number == 0){
  46. this.wait();
  47. }
  48. number--;
  49. System.out.println("--------" + Thread.currentThread().getName() + "减一成
  50. 功----------,值为:" + number);
  51. notifyAll();
  52. }catch (Exception e){
  53. e.printStackTrace();
  54. }
  55. }
  56. }

Lock方案

  1. public class ThreadDemo1 {
  2. private ReentrantLock reentrantLock = new ReentrantLock();
  3. private Condition condition = reentrantLock.newCondition();
  4. private int number = 0;
  5. private void incr() {
  6. reentrantLock.lock();
  7. try {
  8. while (number != 0) {
  9. condition.await();
  10. }
  11. number++;
  12. System.err.println("number::" + number);
  13. condition.signalAll();
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. } finally {
  17. reentrantLock.unlock();
  18. }
  19. }
  20. private void decr() {
  21. reentrantLock.lock();
  22. try {
  23. while (number != 1) {
  24. condition.await();
  25. }
  26. number--;
  27. System.err.println("number::" + number);
  28. condition.signalAll();
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. } finally {
  32. reentrantLock.unlock();
  33. }
  34. }
  35. public static void main(String[] args) {
  36. ThreadDemo1 demo1 = new ThreadDemo1();
  37. new Thread(()->{
  38. for (int i = 0; i < 5; i++) {
  39. demo1.incr();
  40. }
  41. },"AA").start();
  42. new Thread(()->{
  43. for (int i = 0; i < 5; i++) {
  44. demo1.incr();
  45. }
  46. },"BB").start();
  47. new Thread(()->{
  48. for (int i = 0; i < 5; i++) {
  49. demo1.decr();
  50. }
  51. },"CC").start();
  52. new Thread(()->{
  53. for (int i = 0; i < 5; i++) {
  54. demo1.decr();
  55. }
  56. },"DD").start();
  57. }
  58. }