进阶Java编程(2)线程常用操作方法
线程常用操作方法
多线程的主要操作方法都在Thread类中定义的。
1,线程的命名和取得
多线程的运行状态是不确定的,那么在程序的开发之中为了可以获取到一些需要使用到的线程就只能依靠线程的名字来进行操作。所以线程的名字是一个至关重要的概念,这样在Thread类之中就提供有线程名称的处理。
①构造方法:public Thread(Runnable target,String name);
②设置名字:public final void setName(String name);
③取得名字:public final String getName();
对于线程对象的获得是不可能只是依靠一个this来完成的,因为线程的状态不可控,但是有一点是明确的,所有的线程都要执行【run()方法】,那么这个时候可以考虑获取当前线程,在Thread类里面提供有
·范例:观察线程的命名操作
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
MyThread mt=new MyThread();
new Thread(mt,"线程A").start();
new Thread(mt).start();
new Thread(mt,"线程B").start();
new Thread(mt,"线程C").start();
new Thread(mt,"线程D").start();
}
}
当开发者为线程设置名字的时候就是要设置的名称,而如果没有设置名字,则会自动生成一个不重复的名字。这种自动的属性命名主要是依靠了static属性完成的,在Thread类里面定义有如下操作:
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
·范例:观察一个main线程程序
public class Main {
public static void main(String[] args) {
MyThread mt=new MyThread();
new Thread(mt,"线程对象").start();
mt.run();
}
}
main
线程对象
通过此时的代码可以发现当使用了【mt.run()】直接在主方法里面之中调用线程类对象中的【run()】方法所获得的线程的名字为【main】所以可以得出一个结论:主方法也是一个线程。那么现在的问题来了,所有的线程都是在进程上的划分,那么进程在哪里?每当使用Java命令执行程序的时候就表示启动了一个JVM的进程,一台电脑上可以启动若干个JVM进程都会有各自的线程。
在任何的开发之中,主线程可以创建若干个子线程。创建子线程的目的是可以将一些复杂逻辑或者比较耗时的逻辑交由子线程处理。
·范例:子线程的处理
public class Main{
public static void main(String[] args) {
System.out.println("1,执行操作任务一");
new Thread(()->{
int temp=0;
for(int x=0;x<Integer.MAX_VALUE;x++){
temp += x;
}
System.out.println("2,执行操作任务二");
}).start();
System.out.println("3,执行操作任务三");
}
}
主线程负责处理整体流程,而子线程负责处理耗时操作。
2,线程休眠
如果说现在希望某个线程可以暂缓执行,那么就可以使用休眠的处理,在Thread中定义的休眠的方法如下:
·休眠:public static void sleep(long millis) throws InterruptedException;
·休眠:public static void sleep(long millis,int nanos) throws InterruptedException;
在进行休眠的时候有可能会产生中断异常【InterruptedException】,中断异常属于Exception的子类,所以证明该异常必须进行处理。
·范例:观察休眠处理
public class Main{
public static void main(String[] args) {
new Thread(()->{
for(int x=0;x<10;x++){
System.out.println(Thread.currentThread().getName()+"、x="+x);
try {
Thread.sleep(100);//暂缓执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程对象").start();
}
}
·范例:产生多个线程对象进行休眠处理休眠的主要特点是可以实现线程的自动唤醒,以继续进行后续的处理。但是需要注意的是,如果现在有多个线程对象,那么休眠也是有先后顺序的。
public class Main{
public static void main(String[] args) {
Runnable run=()->{
for(int x=0;x<10;x++){
System.out.println(Thread.currentThread().getName()+"、x="+x);
try {
Thread.sleep(100);//暂缓执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for(int num=0;num<5;num++){
new Thread(run,"线程对象-"+num).start();
}
}
}
此时将产生五个线程对象,并且这五个线程对象执行的方法体是相同的。此时从程序执行的感觉上来讲好像若干个程序一起进行了休眠,而后一起进行了自动唤醒,但是实际上是有差别的。
3,线程中断
在之前发现线程的休眠里面提供有一个中断异常,实际上就证明线程的休眠是可以打断的,而这种打断肯定是由其他线程完成的。
·判断线程是否被中断:public boolean isInterrupted();
·中断线程执行:public void interrupt();
·范例:观察线程的中断处理操作
public class Main{
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
System.out.println("【需要睡觉保存体力】");
try{
Thread.sleep(10000);//预计准备休眠10s
}catch (InterruptedException e) {
System.out.println("【睡眠被打断】");
} System.out.println("【睡觉结束可以继续工作了】");
});
thread.start();
Thread.sleep(1000);
if(! thread.isInterrupted()){//该线程中断了吗
System.out.println("【有人来打扰我休息】");
thread.interrupt();//中断执行
}
}
}
【需要睡觉保存体力】 【有人来打扰我休息】 【睡眠被打断】 【睡觉结束可以继续工作了】
所有正在执行的线程都是可以被中断的,中断线程必须进行异常处理。
4,线程强制运行
所谓的线程的强制执行指的是当满足于某些条件之后,某一个线程对象将可以一直独占资源,一直到该线程的程序执行结束。
·范例:观察一个没有强制执行的程序
public class Main{
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
for(int x=0;x<100;x++){
System.out.println(Thread.currentThread().getName()+"执行、x="+x);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"玩耍的线程");
thread.start();
for(int x=0;x<100;x++){
Thread.sleep(100);
System.out.println("【main线程】num="+x);
}
}
}
·强制执行:public final void join() throws InterruptException;这个时候主线程和子线程都在交替执行着,但是如果说现在你希望主线程独占执行。那么我们就可以使用【Thread类】中方法强制执行。
public class Main{
public static void main(String[] args) throws InterruptedException {
Thread mainThread = Thread.currentThread();
Thread thread=new Thread(()->{//获得主线程
for(int x=0;x<100;x++){
if(x==3){
try {
mainThread.join();//主线程要优先执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"执行、x="+x);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"玩耍的线程");
thread.start();
for(int x=0;x<100;x++){
Thread.sleep(100);
System.out.println("【main线程】num="+x);
}
}
}
在进行线程强制执行的时候一定要获取强制执行线程对象之后才可以执行join()调用。
5,线程礼让
线程的礼让指的是现将资源让出去,让别的线程先执行。
·礼让:public static void yield();
·范例:使用礼让操作
public class Main{
public static void main(String[] args) throws InterruptedException {
Thread mainThread = Thread.currentThread();
Thread thread=new Thread(()->{//获得主线程
for(int x=0;x<100;x++){
if(x%3==0){
Thread.yield();//线程礼让执行
System.out.println("礼让其他线程");
}
System.out.println(Thread.currentThread().getName()+"执行、x="+x);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"玩耍的线程");
thread.start();
for(int x=0;x<100;x++){
Thread.sleep(100);
System.out.println("【main线程】num="+x);
}
}
}
礼让执行的时候每一次调用yield()方法都只会礼让一次当前的资源。
6,线程优先级
从理论上来讲线程的优先级越高越有可能先执行(越有可能先抢占到资源)。在Thread类里面针对于优先级的操作提供有如下的两个方法:
·设置优先级:public final void setPriority(int newPriority);
·获取优先级:public final int getPriority()
在定义优先级的时候都是通过int型的数字来完成的,而对于此数字的选择在Thread类里面就定义有三个常量:
①最高优先级:public static final int MAX_PRIORITY、10;
②中等优先级:public static final int NORM_PRIORITY、5;
③最低优先级:public static final int MIN_PRIORITY、1;
·范例:观察优先级
public class Main{
public static void main(String[] args) throws InterruptedException {
Runnable run=()->{
for(int x=0;x<10;x++){
try{
Thread.sleep(1000);
} catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行");
}
};
Thread threadA=new Thread(run,"线程对象A");
Thread threadB=new Thread(run,"线程对象B");
Thread threadC=new Thread(run,"线程对象C"); threadA.setPriority(10);
threadB.setPriority(1);
threadC.setPriority(1); threadA.start();
threadB.start();
threadC.start();
}
}
·范例:主线程的优先级
public class Main{
public static void main(String[] args) throws InterruptedException {
Thread mainThread=Thread.currentThread();
System.out.println(mainThread.getPriority());
}
}
备注:优先级高的只是倾向于先执行,但是并不是一定优先执行。主线程属于中等优先级,而默认创建的线程也是中等优先级。
进阶Java编程(2)线程常用操作方法的更多相关文章
- 进阶Java编程(3)线程的同步与死锁
线程的同步与死锁 1,同步问题引出 在多线程的处理之中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,对于当多个线程访问统一资源的时候如果处理不当就会产生数据的错误 ...
- 菜鸡的Java笔记 - java 线程常用操作方法
线程常用操作方法 线程的命名操作,线程的休眠,线程的优先级 线程的所有操作方法几乎都在 Thread 类中定义好了 线程的命名和取得 ...
- JAVA基础语法:java编程规范和常用数据类型(转载)
JAVA基础语法:java编程规范和常用数据类型 摘要 本文主要介绍了最基本的java程序规则,和常用数据类型,其中侧重说了数组的一些操作. 面向java编程 java是纯面向对象语言,所有的程序都要 ...
- 进阶Java编程(4)多线程深入话题
多线程深入话题 1,优雅的停止线程 在多线程操作之中如果要启动多线程使用的肯定是Thread类中的start()方法,而如果对于多线程需要进行停止处理,Thread类原本提供有stop()方法,但是这 ...
- 进阶Java编程(5)基础类库
Java基础类库 1,StringBuffer类 String类是在所有项目开发之中一定会使用到的一个功能类,并且这个类拥有如下的特点: ①每一个字符串的常量都属于一个String类的匿名对象,并且不 ...
- 进阶Java编程(9)反射与类操作
1,反射获取类结构信息 在反射机制的处理过程之中不仅仅只是一个实例化对象的处理操作,更多的情况下还有类的组成结构操作,任何一个类的基本组成结构:父类(父接口).包.属性.方法(构造方法与普通方法). ...
- 进阶Java编程(6)正则表达式
正则表达式 通过之前一系列的分析可以发现,String是一个非常万能的类型,因为String不仅仅可以支持有各种字符串的处理操作,也支持有向各个数据类型的转换功能,所以在项目的开发之中,只要用户输入的 ...
- 进阶Java编程(1)多线程编程
Java多线程编程 1,进程与线程 在Java语言里面最大的特点是支持多线程的开发(也是为数不多支持多线程的编程语言Golang.Clojure方言.Elixir),所以在整个的Java技术学习里面, ...
- java中 File文件常用操作方法的汇总
一.IO流: 1.全称为:Input Output---------输入输出流. 输入:将文件读到内存中. 输出:将文件从内存中输出到其他地方. 2.IO技术的作用: 主要是解决设备与设备之间的数据传 ...
随机推荐
- 脚本:将git项目下载到本地并启动
大致思路:从git上clone源代码到本地:使用mvn package将源代码达成war/jar包:将打好的包放到tomcatpath/webapps/下:到tomcatpath/bin/下执行res ...
- 计数原理,递推,求从左边能看到l个棒子,右边能看到r个棒子的方案数目
题意 有高为 1, 2, …, n 的 n 根杆子排成一排, 从左向右能看到 L 根, 从右向左能看到 R 根.求有多少种可能的排列方式. solution: 数据范围仅200,本来是往组合数学方 ...
- Qt串口通信专题教程
查看以前的教程:Qt编写串口通信程序全程图文讲解 查看Wincom和Lincom介绍:Qt跨平台串口通信软件Wincom与Lincom 下载软件,文档和源码:资源下载 ——————————————20 ...
- kotlin array
(1)Kotlin语言使用Array表示数组. (2)[] 可以用于访问数组的元素, [] 被进行了操作符的重载,调用的是 Array 类的 setter 和 getter 方法 2.创建数组 (1) ...
- 7.Mahout菩萨
1.Maout简介 2.机器学习介绍 3.Mahout算法介绍
- NLP - Log-linear Models
1.The Language Modeling Problem 现在抛开我们之前讲的马尔科夫模型的假设,对于一门语言的定义,肯定不能简单依赖于每个单词的前两个单词,这是常识.比如英语中 ...
- h5 与原生 app 交互的原理
现在移动端 web 应用,很多时候都需要与原生 app 进行交互.沟通(运行在 webview中),比如微信的 jssdk,通过 window.wx 对象调用一些原生 app 的功能.所以,这次就来捋 ...
- 实现超简单的http服务器
想在Linux下实现一个简单的web Server并不难.一个最简单的HTTP Server不过是一个高级的文件服务器,不断地接收客户端(浏览器)发送的HTTP请求,解析请求,处理请求,然后像客户端回 ...
- 【查看修复HDFS中丢失的块】org.apache.hadoop.hdfs.BlockMissingException: Could not obtain block: BP
首先得好看有多少损坏的文件,其中需要使用Hadoop的fsck命令: 以下是官方解释 用法: hadoop fsck //路径 以上将会展示该路径下所有受损的文件 最后用-delete 可以清除掉 ...
- Array.ConvertAll<TInput, TOutput> 数组相互转化方法
有个需求,把char数组转换为int数组,然后噼里啪啦就弄了这样一堆代码: public static int[] CharArrToIntArr(char[] charArr) { int[] in ...