public class ThreadImpl implements Runnable{ // static修饰 ,为了共享,(static不能和this连用) private static int num = 1;// 要打印的数 private static int count = 0;// 计数 三次一轮回 private int n;// 表示线程的编号 private Object object;// 定义锁对象 private int max;// 要打印的最大数 private int threadsNum;// 线程个数 private int times;// 每个线程每回打印次数 @Override public void run() { synchronized (object) {// object 表示同步监视器,是同一个同步对象 while (num <= max) { object.notifyAll();// 唤醒所有线程,(wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用) try { while(count % threadsNum != (n - 1)){// 找出下一个线程 不正确的线程等待 object.wait();// 此线程让出资源,等待,(sleep()释放资源不释放锁,而wait()释放资源释放锁;) } System.out.print(Thread.currentThread().getName() + " ");//输出线程名字 while(num <= max){ if (num%times==0 || num==max) { System.out.println(num++);//最后一个要打印的数不输出逗号,(强迫症,哈哈) } else { System.out.print(num++ + ","); } if ((num - 1) % times == 0) {// 打印了相应次数之后 count++;// 计数器+1,下次循环切换线程 break;//跳出当前while循环 } } } catch (InterruptedException e) { e.printStackTrace(); } } System.exit(0);// 终止程序,(停止寻找锁对象) } // (同步方法的同步监听器其实的是 this) } /** * @desc 有参构造器 * @param object要处理的对象 * @param n线程的编号 * @param max要打印的最大数 * @param threadsNum线程个数 * @param times每个线程每次打印的次数 */ public ThreadImpl(Object object, int n, int max, int threadsNum, int times) { this.object = object; this.n = n; this.max = max; this.threadsNum = threadsNum; this.times = times; } } /** * @desc 有两个线程可以实现每次打一个且是递增的打印 */ public class CeShi02 { public static void main(String[] args) { Object object = new Object();// 创建一个锁对象 int max = 75;// 要打印的最大数 int threadsNum = 2;// 线程个数 int times = 1;// 每个线程每回打印次数 for (int i = 1; i <= threadsNum; i++) { new Thread(new ThreadImpl(object, i, max, threadsNum, times), "线程" + i).start();// 开启三个线程,都处理这个对象,并给线程添加序号和命名 } }