关于多线程取球放球的问题(语言-java)

学习多线程时,想写一个取球放球的代码,然后想要循环这个操作10次,但是最终只执行了1次。

以i++模拟放球,i--模拟取球

public class SyncTest {
    private static int i=0;
    static class Thread1 implements Runnable{

        @Override
        public  void run() {
            for (int a=0;a<10;a++){
                synchronized(this){
                    if (i > 0) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    i++;
                    notify();
                    System.out.println(i);
            }
        }
        }
    }
    static class Thread2 implements Runnable{

        @Override
        public  void run() {
            for (int a=0;a<10;a++) {
                synchronized (this) {
                    if (i == 0) {
                        try {
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    i--;
                    notify();
                    System.out.println(i);
                }
            }
        }
    }
    public static void main(String[] args) {
        new Thread(new Thread1()).start();
        new Thread(new Thread2()).start();
    }
}

img

img

debug后发现两个线程都wait了。如果不在线程这两个线程终做循环,而是在主线程去循环创建线程可以达到效果,但是一直创建和销毁线程又不太好。

有什么更好的方法吗

package com;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**

  • @Description:

  • @ClassName: test3

  • @Author: yokna

  • @Date: 2021/12/17 14:59

  • @Version: 1.0

  • /
    public class test3 {
    private static int i=0;
    private static String lock = "";
    static class Thread1 implements Runnable{

      @Override
      public  void run() {
          for (int a=0;a<10;a++){
              synchronized(lock){
                  if (i > 0) {
                      try {
                          lock.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  i++;
                  lock.notify();
                  System.out.println(i);
              }
          }
      }
    

    }
    static class Thread2 implements Runnable{

      @Override
      public  void run() {
          for (int a=0;a<10;a++) {
              synchronized (lock) {
                  if (i == 0) {
                      try {
                          lock.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  i--;
                  lock.notify();
                  System.out.println(i);
              }
          }
      }
    

    }
    public static void main(String[] args) {

      new Thread(new Thread1()).start();
      new Thread(new Thread2()).start();
    

    }

}

你似乎没有理解内部类this关键字代表的意思,两个this代表着不同的对象,sync锁的是对象,相当于两把锁,每次执行到wait的时候,线程就挂起了,也等不到其他线程唤醒,因为锁对象不一样,所以只会执行一次。

img


这样解释,你就会很直观的看出来了。