import java.util.Scanner;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
* 需求:
* 启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5,
* 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15.
* 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到键盘录入的那个值.
* 思路:
* 1.键盘录入一个数值
* 2.定义三个线程
*
* */
//总数类
class Rouse{
private int max; //定义一个执行的最大值 -- 上限
private int n = 1; //当前的次数
private Lock lock = new ReentrantLock(); //实际化一个锁
//Rouse自带的共享代码块
public void println() {
while((n+1)<max){
//上锁
lock.lock();
//下面两条语句将线程名转成int 类型 供之后使用
/*因为线程的交替有序打印要涉及切换,转换成int 类型有利于切换
*
* */
String a = Thread.currentThread().getName(); //获取正在执行的线程名字
int c = Integer.parseInt(a); //获取的是当前进程的int类型
int num = (n/5)%3+1; //得到的是 现在轮到应该那个线程运行 int 数值
//如果进来的线程c 与 num相同则运行打印
if(c == num) {
System.out.println("以下是"+a+"线程正在运行");
for(int i = 0;i < 5;i++) {
if(n>max) {
continue;
}
System.out.println("当前线程"+Thread.currentThread().getName()+"正在打印: "+n);
n++;
}
}else { //相反如果不是则释放运行资格
Thread.yield();
}
//释放锁
lock.unlock();
}
}
public Rouse(int max) {
this.max = max;
}
}
//计数的线程类
class sumadd implements Runnable{
int n; //进程的名字
Rouse r; //初始化给Rouse对象
@Override
//从Runnable 实行下来的方法
public void run() {
System.out.println("运行类被调用了");//用于调试
r.println();
}
public sumadd(Rouse r) {
// TODO 自动生成的构造函数存根
this.r = r;
}
}
//运行线程运行类
class Run{
private int n; //接受键盘录入的最大值
public void run()
{
Rouse r = new Rouse(n);
sumadd p = new sumadd(r);
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
//修改线程的名字 有利于之后 String 转换成 int 类型
t1.setName("1");
t2.setName("2");
t3.setName("3");
//开启线程
t1.start();
t2.start();
t3.start();
}
public Run(int n) {
this.n = n;
}
}
//从键盘获取输入值的类
class Sc{
private int n;
private Scanner sc = new Scanner(System.in);
public int getInt() {
System.out.println("请输入一个上限:");
n = sc.nextInt();
return n;
}
}
public class Ab {
//主类只负责两件事:1获取上限值
public static void main(String[] args) throws InterruptedException {
int n = new Sc().getInt();
new Run(n).run();
}
}