先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验。
不知道大家有没有这种感觉,在公司项目忙碌的时候,有时候感觉又忙又累,甚至加班通宵都有,能忙死人,每天想着轻松点吧,能休息休息做点别的什么。
但是当项目收尾不忙(不忙是指不用加班)的时候,如果一天两天还好,但是时间超出一周(不是没事干,是不像之前每天加班才能完成任务,现在每天8个小时不到就完成了任务),总是感觉太闲了,不太充实了,不知道该干什么。这边找点事,那边找点事
有时候甚至想着还是忙点吧。
所以趁着最近几天不是太忙,对自己做了一个复盘,发现我计划的东西还有一半没有完成(比如:我读的书 和 写的教程还只是做到2/1),所以还要加油,更主要的是 公众号文章的更新以后要保持下去。
好了不发感慨了,开始我们今天的线程篇(这些文章目前已经做了分类,多了就能成系统了)。
1,sleep和wait概念
Java中的多线程是一种抢占式的机制。
线程主要有以下几种状态:可运行,运行,阻塞,死亡。抢占式机制指有多个线程处于可运行状态,但是只有一个线程在运行。
当有多个线程访问共享数据的时候,就需要对线程进行同步。线程中的几个主要方法的比较:
Thread类的方法:sleep(),yield()等
Object的方法:wait()和notify()等
每个对象都有一个机锁来控制同步访问。Synchronized关键字可以和对象的机锁交互,来实现线程的同步。
由于sleep()方法是Thread类的方法,因此它不能改变对象的机锁
Wait()方法和notify()方法:当一个线程执行到wait()方法时(线程休眠且释放机锁),它就进入到一个和该对象相关的等待池中,同时失去了对象的机锁。
当它被一个notify()方法唤醒时,等待池中的线程就被放到了锁池中。该线程从锁池中获得机锁,然后回到wait()前的中断现场。
共同点: 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
不同点: Thread.sleep(long)可以不在synchronized的块下调用,而且使用Thread.sleep()不会丢失当前线程对任何对象的同步锁(monitor);
object.wait(long)必须在synchronized的块下来使用,调用了之后失去对object的monitor, 这样做的好处是它不影响其它的线程对object进行操作。
2. sleep和wait方法的应用场景
sleep 休眠方法:
Static void sleep(long ms)
该方法会使当前线程进入阻塞状态指定毫秒,当阻塞指定毫秒后,当前线程会重新进入Runnable状态,等待划分时间片。
wait方法一般是跟notify方法连用的:
多线程之间需要协调工作。如果条件不满足则等待。当条件满足时,等待该条件的线程将被唤醒。在Java中,这个机制实现依赖于wait/notify。
3,简单使用
一,Sleep()
Sleep方法属于Thread类,调用Sleep时会暂停此线程指定的时间,但它的监控一直在监控着,Sleep不会释放对象的锁,到了一定时间它会自动唤醒。
Sleep方法有接收时间参数,Therad.Sleep(1000) 其中参数都是毫秒值。
public class ThreadSleep {
public static void main(String[] args) {
// write your code here
int time = 10;
for (int i=1;i<=time;i++) {
try {
Thread.sleep(1000);
System.out.println("线程休眠时间=" + i +"秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
上面的代码循环中间隔一秒输出一个信息。
线程休眠时间=1秒
线程休眠时间=2秒
线程休眠时间=3秒
线程休眠时间=4秒
线程休眠时间=5秒
线程休眠时间=6秒
线程休眠时间=7秒
线程休眠时间=8秒
线程休眠时间=9秒
线程休眠时间=10秒
Process finished with exit code 0
二,Wait()
1.Wait()方法属于Object类,调用Wait方法时,线程会放弃对象锁,进入等待此对象的等待锁定池,只有此对象调用notify()方法后本线程才进入对象锁定池准备,wait方法需要被动唤醒,
2. wait方法不需要时间参数
public class ThreadWait {
public static void main(String[] args) {
/*** 作者:公众号:程序职场
* 代码描述:创建两个线程一个操作年龄的信息,一个是工作量的信息
*/
//输出年龄信息
Object obj=new Object();
Thread download=new Thread(){
public void run() {
System.out.println("开始输出年龄");
for (int i = 1; i < 6; i+=1) {
System.out.println("年龄="+i);
}
System.out.println("年龄输出成功");
synchronized (obj) {
System.out.println("唤起");
obj.notify();//唤起wait的等待
}
System.out.println("开始输出工作量");
for (int i = 1; i < 6; i+=1) {
System.out.println("工作量="+i+"小时");
}
System.out.println("工作量输出成功");
}
};
//2.年龄输出成果的结果
Thread show=new Thread(){
public void run(){
synchronized (obj) {
try {
System.out.println("阻塞");
obj.wait();//阻塞当前
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("年龄完成");
}
}
};
download.start();
show.start();
}}
1,show线程中阻塞线程(wait)
2,download线程中 唤醒(notify)
本文 Github ( 码云Gitee同步) https://github.com/ProceduralZC/JavaDevGuide/tree/master/code/JavaTheead/ThreadClass 已收录,欢迎 star。
我是【尔东双月】一枚执着的职场程序员,微信搜索【程序职场】关注我。别忘了三连啊,点赞、收藏、留言,随意给,我不挑。
知乎号: 程序职场
注:如果文章有任何问题,欢迎毫不留情地指正。