Gitee仓库地址:Tinsur/Java基础学习记录 – 码云 – 开源中国
Thread.sleep();
阻塞线程休眠,但不释放锁
举例:
static void main() throws InterruptedException {
// for (int i = 0; i < 10; i++) {
// Thread.sleep(Duration.ofSeconds(1));
// //当前线程休眠1秒,阻塞
// IO.println(i);
// }
Thread t1 = new Thread(){
@Override
public void run() {
IO.println("Hello,im thread 1");
try{
Thread.sleep(2000);
}catch (InterruptedException e){
throw new RuntimeException(e);
}
IO.println("I'm over");
}
};
t1.start();
}
另一种写法
//另外一种写法
TimeUnit.SECONDS.sleep(2);
wait和notify
使用wait休眠要使用锁(lock),只能通过锁对象来进行调用,因此只能在同步块或者同步方法中使用,与sleep的区别是wait是释放锁的,也就意味着在此线程阻塞的时候,其他共享同一把锁的线程可以继续执行。
示例如下:新建一个CountTask任务
public class CountTask implements Runnable{
public byte[] lock = new byte[0];
@Override
public void run() {
synchronized(lock){
for (int i = 0; i < 10; i++) {
try {
lock.wait(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
IO.println(i);
}
}
}
}
测试类:
public class test02 {
static void main() {
CountTask ct = new CountTask();
Thread t1 = new Thread(ct);
t1.start();
}
}
wait有多个重写方法,如果不写入任何参数,则无限期休眠。,示例如下:
修改CountTask任务类:
public class CountTask implements Runnable{
public byte[] lock = new byte[0];
public boolean dontWait = false;
@Override
public void run() {
synchronized(lock){
for (int i = 0; i < 10; i++) {
try {
if(!dontWait){
lock.wait();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
IO.println(i);
}
}
}
}
此时若不唤醒,则进程永久阻塞,所以还要添加唤醒条件和唤醒操作,修改测试类:
public class test02 {
static void main() throws InterruptedException {
CountTask ct = new CountTask();
Thread t1 = new Thread(ct);
t1.start();
Thread.sleep(2000);
//休眠2秒之后,将线程唤醒
synchronized (ct.lock){
ct.dontWait = true;
//随机唤醒一个睡眠的线程
ct.lock.notify();
//唤醒所有睡眠的线程
ct.lock.notifyAll();
}
}
}
此处需要注意,用哪把锁执行的wait,就要用哪把锁唤醒。
定时任务
import java.util.Timer;
import java.util.TimerTask;
public class Test03 {
static void main() {
//定时任务
TimerTask tt = new TimerTask() {//TimerTask是一个内部类
@Override
public void run() {
IO.println("起床学习了");
}
};
//创建一个定时器
Timer timer = new Timer();
timer.schedule(tt,3000);
}
}
线程池
Java 5引⼊线程池。线程池相关类主要有:Executor、ExecutorService、Executors等等。
常见的几种线程池:
//创建一个仅有单个线程的线程池
ExecutorService es1 = Executors.newSingleThreadExecutor();
//创建拥有固定数量限制的线程池
ExecutorService es2 = Executors.newFixedThreadPool(10);
//创建可缓存无限数量线程的线程池
ExecutorService es3 = Executors.newCachedThreadPool();
//创建一个执行定时任务的线程池
ScheduledExecutorService es4 = Executors.newScheduledThreadPool(5);
//JDK25特有的:创建java绿色线程(虚拟线程、协程)的线程池
ExecutorService es5 = Executors.newVirtualThreadPerTaskExecutor();
演示:
es2.submit(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
IO.println(i);
}
}
});
//close会阻塞,等待所有任务结束后才会关闭线程池
//es2.close();
//IO.println("主线程结束");
特别的,定时任务线程池用法:
//定时任务线程池
ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);
//延迟一段时间执行任务
ses.schedule(new Runnable() {
@Override
public void run() {
IO.println("起床了");
}
},10, TimeUnit.SECONDS);
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
IO.println("学累了,玩一会");
}
},1,3,TimeUnit.SECONDS); //首次延迟1秒,之后每3秒执行一次
IO.println("主线程结束");
}
THE END

暂无评论内容