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() + "\t");//输出线程名字
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();// 开启三个线程,都处理这个对象,并给线程添加序号和命名
}
}