开始
线程,是JAVA中一个比较重要的环节,而关于线程,就存在多线程,生命期,线程池等等一大堆的东西。今天想说的东西,就涉及多线程和生命期,所以我打算在说的同时对它们进行复习。
正文
概念的说明
- 多线程:就是一大堆的线程,它们在对CPU执行权的抢夺上向来是你不让我,我不让你,而且还相当的蛮横。(真不晓得如果线程里存在踩踏事件会产生多么严重的后果)
- 锁:为了防止线程之间的你来我往把CPU搞得一团糟,就开始有了锁的概念,指在一段时间内仅允许一个线程运行。这就大大降低了CPU的血压,妙的苦。
- 线程池:而存放这些顽皮的线程的地方,就是线程池。(想必池子应该很坚固)
- 线程的生命期:对线程这些行为的刻画,总结,就是生命期,一般情况下,线程的生命期指的是线程出生到入土的过程,啊不对,是出生到运行完后被清除的过程,期间线程的行为活动就是生命期的一部分,比如争抢CPU的执行权,中场休息等等。
问题描述
而就在最近,我发现一个很离谱的现象,用言语表达的话我估计会比较逊色,而且晦涩难懂。所以上代码如下
private long milk=10;
private Object obj=new Object();
@Override
public void run(){
synchronized (obj){
if(milk>0)
{
try {
System.out.println("拿走了一瓶牛奶");
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
milk--;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("补充了一瓶牛奶");
milk++;
}
//以上为实现类中的部分内容,感觉核心应该就是run方法
//测试文件内容
Runnable ra=new RunableA();
Scanner sc=new Scanner(System.in);
System.out.println("请输入你想卷入的人数");
int i=sc.nextInt();
ArrayList<Thread> ttarray=new ArrayList<>();
for(;i>0;i--){
ttarray.add(new Thread(ra,"第"+i+"位"));
}
System.out.println("载入完毕,准备开始,请稍等...");
Thread.sleep(1000);
//关键部分
for(Thread t:ttarray){
t.start();
}
System.out.println("牛奶还剩"+ra.getMilk()+"瓶");
结果
请输入你想卷入的人数
2
载入完毕,准备开始,请稍等...
拿走了一瓶牛奶
牛奶还剩10瓶 //println运行完毕
拿走了一瓶牛奶
补充了一瓶牛奶
补充了一瓶牛奶
进程已结束,退出代码0
结果中显示,在运行这个程序时,测试文件里位于 运行线程部分后面 的代码会被提前运行,也就是说后面的println会在线程运行的过程中执行。
这就产生了一个问题了,println是给了CPU什么好处才能在线程运行的时候插队的?
猜想
- 就是多线程的底层原理好像是一个CPU反复来执行这几个线程,可能再交换使用权的时候,jvm偷偷把println执行了。 然后debug让jvm执行慢了,就不会提前执行println(引自学长)
这个问题的原因反正我是实在想不出来,就用这篇博客记录一下吧
总结
线程真的好奇怪啊。
其他
有没有大佬知道的,请在评论区为我解答一下,届时记得踢我一下,用力点。