IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 线程应用--简单倒计时,线程问题你真的了解吗,sleep是精确的吗【深挖基础】【java养成】 -> 正文阅读

[Java知识库]线程应用--简单倒计时,线程问题你真的了解吗,sleep是精确的吗【深挖基础】【java养成】

Java学习打卡:第二十五天

Java养成计划(打卡第25天)


内容管理

今天分享一些基本的,以前漏掉的java知识,查漏补缺最好的方式还是实践,只有灵活的运用之后才能发现自身存在的问题。

预定义标注类型

之前你了解过一些javadoc注释,在java核心API里面包含一些预定义的标注类型,其中包含Deprecated,Override,Suppress Warrings

Deprecated

标记标注类型,当程序中的元素有更好的替代品存在时,就可以使用该类型的标注,表示该程序元素是过时的,当编译器检测到时就会警告

@Deprecated//表示该方法过时
	public String getCry() {
		return "ahch";
	}

Override

标记标注类型,指明方法是一个重写方法,当发现子类的标注过的方法并没有覆盖超类方法时就会报错

@Override//表示该方法是重写的
	public String getName() {
		return "dog";
	};

Suppress Warrings

这个标注类型包含一个String[]类型的value,用该类型的标注修饰某个程序元素时可以抑制针对该元素的警告信息

用法是

@SuppressWarrings(“deprecation”) //这就抑制了Deperated类型的警告信息

public static void mian(String[] args)
{
    @SuppressWarrings("deprecation")
    Object o = new Object();
    o.getCry(); //这个方法是被弃用的,但是这里不会给出警告,警告被抑制
}

其余还有Inherited,Retention,Target等标注,等之后实例中用到的时候再谈

线程与同步

之前的了解中只是简单了解了一下多线程的两种方式一种是扩展Thread,另外一种是实现Runnable,以及简单的线程同步

两种方法的共性

  • 线程是对象,一个线程是Thread类的实例或者是其子类的实例,扩展就是子类实例,实现方式就是Thread实例
  • 线程通过执行特定对象的特定方法来完成相应的任务,线程启动后都是执行的线程对象的run() 方法
  • 线程的启动都是通过start方法启动,不能显式调用run方法,如果调用就只是普通的方法,就不会达到多线程的目的

调用的run()方法都是线程对象的方法,这里扩展Thread类好理解,创建了几个子类线程对象,调用其方法,那么实现接口方式的线程对象是怎么回事

我们可以查看Thread类的run源码

public void run(){
	if(target != null)
    {
        target.run();
    }
}

target就是传递给构造方法的那个Runnable对象,所以只要在创建对象时指定了Runnable对象,最终执行的就是那个对象的run方法。

线程控制

除了start,run之外,Thread还有其他诸如sleep的方法,在介绍方法之前先来介绍一下线程状态与线程优先级

线程状态

之前的介绍知道线程经start()启动之后不会马上进入执行状态(running),而是县进入就绪状态,等待CPU的控制和分配,而处于执行状态下的线程也可能会被剥夺控制回到就绪(ready)状态,另外还有就是执行中的线程可能因为某些阻塞事件被迫放弃CPU控制,进入等待(waiting)状态。

在这里插入图片描述
执行中的线程也可能会由于某种阻塞事件而丧失继续占有CPU的理由

  • 等待I/O操作的完成(比如控制台输入之类的)
  • 调用sleep()方法,主动进入休眠
  • 调用synchronized方法或语句不能获得相应的对象
  • 一个对象不满足当前线程继续执行处理,线程主动调用wait方法

当这类事件发生时,执行的线程就会放弃CPU,进入等待状态,当阻塞事件消除时,相应的线程由等待状态转变为就绪状态等待执行,重新调度

线程优先级

在java中,每一个线程都有优先级,取值从1到10,Thread类中定义了一些与优先级有关的量

  • static int MIN_PRIORITY = 1;

  • static int NORM_PRIORITY = 5

  • static int MAX_PRIORITY = 10;

  • void setPriority(int newPriority) //设置线程的优先级

  • final int getPriority() //返回线程优先级,不可以重写

main线程的默认优先级为5,一个新建线程的优先级等于创建它的父线程的优先级

线程的调度策略分为先占式和轮转式,这个等之后讲到线程池的时候再提

yield() //当前线程放弃CPU进入就绪状态

这是一个Thread类的一个静态方法,该方法可以使当前执行的线程进入就绪状态

这里有两种可能

  • 没有其他就绪线程存在,刚放弃的CPU马上重新获得并投入执行
  • 有其他就绪线程,就要看具体的调度程序,如果优先级相同,就在其他里选择一个,如果优先级更高,那还是优先执行
sleep(long millis) //使当前执行的线程进入睡眠状态

这也是一个静态方法,使当前线程放弃CPU进入休眠状态,时间到后就绪等待调度,long型数值为毫秒

  • 这个方法不能用于精确定,因为时间到后并不是马上就可以执行

执行该方法要检查InterruptedException,接下来写一个简单的计时器,线程运行时,间隔3秒输出当前所剩的时间

首先要分析,既然是计时器,那么就要有一个记录时间的函数,那就是System里面提供的currentTimeMills方法,返回1970年1、1到现在的毫秒数,之后我们创建一个线程,让这个线程休眠,这里我们只创建这一个线程,所以就会执行的

这里我们?就是依靠这个时间会自己变化,我们就让原来的时间加上一个原来的毫秒数,在沉睡期间时间是在变化的,所以就直接用max函数比较就可,只是要强制转换

package ThreadDemo;

public class ThreadDemo implements Runnable{
	int allTime;
	public ThreadDemo(int alltime) {
		this.allTime = alltime;
		new Thread(this).start(); //这里就创建一个线程对象,我们的构造函数是含参的,这里就要用this指代对象
	}
	@Override
	public void run() {
		System.out.println("Now the time is " + allTime);
		long newtime = System.currentTimeMillis() + allTime* 1000; //变换的时间,注意换算
		while(true)
		{
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}//沉睡3秒
			allTime = (int)Math.max(0,(newtime - System.currentTimeMillis())/1000);  //double类型要强制类型转换
			System.out.println("Now the time is " + allTime);
			if(allTime == 0)
				break;
		}
	}
	public static void main(String[] args) {
		new ThreadDemo(60);
	}
}

这里由于主线程的影响,最开始的数据不是57,而是56,这就是因为这里不只是只有一个线程,但是之后就规律了

Now the time is 60
Now the time is 56
Now the time is 53
Now the time is 50
Now the time is 47
Now the time is 44
Now the time is 41
Now the time is 38
Now the time is 35
Now the time is 32
Now the time is 29
Now the time is 26
Now the time is 23

这里的线程的应用十分广泛,明天会继续分享剩下的同步互斥以及其他的应用~~~

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:08:22  更:2021-10-09 16:09:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:01:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码