线程操作的方法
来源:互联网 发布:h3c s7506e 端口聚合 编辑:程序博客网 时间:2024/06/14 15:23
从线程状态 的图中可以发现,在Java实现多线程的程序中,虽然Thread类实现了Runnable接口,但是操作线程的主要方法并不在Runnable接口中,而是在Thread类中。
Thread类中主要方法
下面介绍几种常用的线程操作方法。
- 取得和设置线程的名称
在Thread类中可以通过getName()方法取得线程的名称,还可以通过setName()方法设置线程的名称。
线程的名称一般在启动线程前就设置,但是也可以为在运行的线程设置名称。允许两个线程拥有相同的名称,但应该尽量避免这种情况的发生。
如果没有设置线程的名称,系统会为其自动分配名称。
【取得和设置线程的名称】
class MyThread implements Runnable{ public void run(){ for(int i=0;i<3;i++){ System.out.println(Thread.currentThread().getName()+ "运行,i="+i);//取得线程的名称 } }};public class ThreadNameDemo{ public static void main(String args[]){ MyThread my=new MyThread();//定义Runnable子类对象 new Thread(my).start();//系统自动设置线程的名称 new Thread(my,"线程-A").start();//手动设置线程的名称 new Thread(my,"线程-B").start(); new Thread(my).start(); }}
运行结果:
线程-A运行,i=0Thread-1运行,i=0线程-B运行,i=0线程-B运行,i=1线程-B运行,i=2Thread-0运行,i=0Thread-1运行,i=1线程-A运行,i=1Thread-1运行,i=2Thread-0运行,i=1Thread-0运行,i=2线程-A运行,i=2
从程序的运行结果中可以发现,没有设置线程名称的线程对象也有了名字而且都是有规律的,分别是Thread-1、Thread-0,从之前讲解的static关键字可以知道,在Thread类中避让存在一个static类型的属性,用于为线程的命名。
了解了以上代码后,下面观察以下的代码
【观察代码的输出】
class MyThread implements Runnable{ public void run(){ for (int i=0;i<3 ;i++ ) { //取得当前线程的名字 System.out.println(Thread.currentThread().getName()+"运行, i="+i); } }}public class CurrentThreadDemo{ public static void main(String args[]) { MyThread my=new MyThread();//定义Runnable子类对象 new Thread(my,"线程").start();//启动线程 my.run();//直接使用run方法 }}
运行结果:
main运行, i=0线程运行, i=0main运行, i=1main运行, i=2线程运行, i=1线程运行, i=2
在以上程序中,主方法直接通过Runnable接口的子类对象调用其中的run()方法,另外一个是通过线程对象调用start()方法启动的,从结果中可以发现,主方法实际上也是一个线程。
另外要提醒的是,在java中所有的现车都是同时启动的,哪个线程先抢到了CPU的资源,哪个线程就先运行。
说明:Java程序中每次裕兴程序至少启动两个线程。 从之前的学习中可以知道,每当使用Java命令执行一个类时,实际上都会启动一个JVM,每个JVM实际上就是在操作系统中启动了一个进程,,Java本身具有垃圾回收机制。所以在Java运行时至少会启动两个线程,一个main线程,另一个就是垃圾收集线程。
2. 判断线程是否启动
通过前面的讲解可知,通过Thread类中的start()方法通知CPU这个线程已经准备好启动了,然后等待CUP资源,运行此线程,在Java中可以使用isAlive()方法来测试是否已经启动而且任然在运行。
【判断线程是否启动】
class MyThread implements Runnable{ public void run(){//覆写run()方法 for(int i=0;i<3;i++){ System.out.println(Thread.currentThread().getName()+ "运行,i="+i);//取得线程的名称 } }};public class ThreadAliveDemo{ public static void main(String args[]) { MyThread my = new MyThread();//实例化Runnable子类对象 Thread t=new Thread(my,"线程");//实例化Thread对象 System.out.println("线程开始执行之前--》"+t.isAlive());//判断线程是否启动 t.start();//启动线程 System.out.println("线程开始执行之后——》"+t.isAlive());//判断线程是否启动 for (int i=0;i<3 ;i++ )//循环输出三次 { System.out.println("main 运行--》"+i); } System.out.println("代码执行之后--》"+t.isAlive());//后面的输出结果不确定 }}
运行结果:
线程开始执行之前--》false线程开始执行之后——》truemain 运行--》0main 运行--》1main 运行--》2代码执行之后--》true线程运行,i=0线程运行,i=1线程运行,i=2
以上的代码运行结果是不确定的,有可能到最后线程已经不存活了,但也有可能继续存活,这要看哪个线程先运行。因为线程操作的不确定性,所以当主线程结束时,那么其他线程不会受到影响,并不会随着主线程的结束而结束。
3. 线程的强制运行
在线程操作中,可以使用join()方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,必须等待此线程完成之后才能继续执行。
【线程的强制运行】
class MyThread implements Runnable{ public void run(){ for (int i=0;i<20 ;i++ ) { System.out.println(Thread.currentThread().getName()+"运行--》"+i); } }};public class ThreadJoinDemo{ public static void main(String args[]) { MyThread my=new MyThread(); Thread t=new Thread(my,"线程"); t.start(); for (int j=0;j<10 ;j++ ) { if (j>5) { try { t.join();//强制t进行强制进行 } catch (Exception e) { } } System.out.println("Main 线程运行-->"+j); } }}
运行结果:
Main 线程运行-->0线程运行--》0Main 线程运行-->1Main 线程运行-->2Main 线程运行-->3线程运行--》1Main 线程运行-->4线程运行--》2Main 线程运行-->5线程运行--》3线程运行--》4线程运行--》5线程运行--》6线程运行--》7线程运行--》8线程运行--》9线程运行--》10线程运行--》11线程运行--》12线程运行--》13线程运行--》14线程运行--》15线程运行--》16线程运行--》17线程运行--》18线程运行--》19Main 线程运行-->6Main 线程运行-->7Main 线程运行-->8Main 线程运行-->9
从上面的结果可以看出,主线程必须等待这个强制运行的线程完成之后才会继续执行。
4. 线程的休眠
在程序中允许一个线程进行暂时休眠,直接调用Thread.sleep()方法即可实现休眠。
【线程的休眠】
class MyThread implements Runnable{ public void run(){ for (int i=0;i<5 ;i++ ) { try { Thread.sleep(500);//线程休眠 } catch (Exception e) { } System.out.println(Thread.currentThread().getName()+"运行,i="+i); } }};public class ThreadSleepDemo{ public static void main(String args[]) { MyThread my=new MyThread();//实例化对象 new Thread(my,"线程").start();//启动线程 }}
运行结果:
线程运行,i=0线程运行,i=1线程运行,i=2线程运行,i=3线程运行,i=4
以上程序在执行时,每次输出都会间隔500ms,达到延迟操作的效果。
5. 中断线程
当一个线程运行时,另一个线程可以通过interrupt()方法即可实现休眠。
【线程的中断】
class MyThread implements Runnable{ public void run(){ System.out.println("1、进入run方法 "); try { Thread.sleep(10000);//休眠10s System.out.println("2、已经完成休眠"); } catch (Exception e) { System.out.println("3、休眠被终止了"); return;//让程序返回被调用处 } }}public class ThreadInterruptDemo{ public static void main(String args[]) { MyThread my=new MyThread();//实例化Runnable接口对象 Thread t=new Thread(my,"线程");//实例化线程对象 t.start(); try { Thread.sleep(2000);//停止2S后再中断 } catch (Exception e) { } t.interrupt();//中断线程 }}
运行结果:
1、进入run方法 3、休眠被终止了
从以上程序运行的结果可以看出,一个线程启动之后进入了休眠状态,原本是休眠10s后继续运行,但是主方法在线程启动的2s后就将其中断了,休眠一旦中断,就执行catch中的代码,并利用里面的return语句返回程序的调用处。
6. 后台线程
在Java程序中,只要前台有一个线程在运行,则整个Java进程就不会消失,所以此时可以设置一个后台线程,这样Java进程结束了,此后台线程依然会继续执行。使用setDaemon()方法即可。
【后台线程的设置】
class MyThread implements Runnable{ public void run(){ while (true)//无限循环 { System.out.println(Thread.currentThread().getName()+"在运行。"); } }}public class ThreadDaemonDemo{ public static void main(String args[]) { MyThread my=new MyThread(); Thread t=new Thread(my,"线程"); t.setDaemon(true);//设置为后台线程 t.start(); }}
在线程MyThread类中,尽管run()方法中是死循环的方式,但是程序依然可以执行完,因为方法在中死循环的线程操作已经设置为了后台运行了。
7. 线程的优先级
在Java的线程操作中,所有的线程在运行前都会保持在就绪状态,那么此时,哪个线程的优先级高,哪个线程就可能会先被执行。
线程的优先级:
优先级越高,越有可能先执行。
在Java的线程中使用setPriority()方法可以设置一个线程的优先级,在Java的线程中一共有3中优先级:
不同优先级的线程执行结果。
【测试线程优先级】
class MyThread implements Runnable{ public void run(){ for (int i=0;i<5 ;i++ ) { try { Thread.sleep(500); } catch (Exception e) { } System.out.println(Thread.currentThread().getName()+"运行,i="+i); } }};public class ThreadPriorityDemo{ public static void main(String[] args) { Thread t1=new Thread(new MyThread(),"线程A"); Thread t2=new Thread(new MyThread(),"线程B"); Thread t3=new Thread(new MyThread(),"线程C"); t1.setPriority(Thread.MIN_PRIORITY);//设置优先级为最低优先级 t2.setPriority(Thread.MAX_PRIORITY);//设置优先级为最高优先级 t3.setPriority(Thread.NORM_PRIORITY);//设置优先级为中等优先级 t1.start(); t2.start(); t3.start(); }}
运行结果:
线程B运行,i=0线程A运行,i=0线程C运行,i=0线程B运行,i=1线程C运行,i=1线程A运行,i=1线程B运行,i=2线程C运行,i=2线程A运行,i=2线程B运行,i=3线程A运行,i=3线程C运行,i=3线程B运行,i=4线程C运行,i=4线程A运行,i=4
从上面的运行结果可以观察到,线程将根据其优先级的大小来决定哪个线程会先运行,但是读者一定要注意的是,并非线程的优先级越高就一定优先执行,哪个线程先执行将由CPU决定。
主线程的优先级是NORM_PRIORITY
8. 线程的礼让
在线程操作中,也可以使用yield()方法将一个线程的操作暂时让给其他线程执行。
【线程的礼让】
class MyThread implements Runnable{ public void run(){ for (int i=0;i<5 ;i++ ) { System.out.println(Thread.currentThread().getName()+"运行-->"+i); if (i==2) { System.out.print("线程礼让:"); Thread.currentThread().yield();//线程礼让 } } }};public class ThreadYieldDemo{ public static void main(String args[]) { MyThread my=new MyThread(); Thread t1=new Thread(my,"线程A"); Thread t2=new Thread(my,"线程B"); t1.start(); t2.start(); }}
运行结果:
线程A运行-->0线程B运行-->0线程B运行-->1线程B运行-->2线程礼让:线程A运行-->1线程A运行-->2线程礼让:线程B运行-->3线程B运行-->4线程A运行-->3线程A运行-->4
从结果就可以发现,每当线程满足条件时(i==2),就会将本线程暂停,而让其他线程先执行。
好了,以上就是线程常用的几种操作了。
- 操作线程的方法
- 线程操作的方法
- 操作线程的方法
- Java 线程操作的相关方法
- C#跨线程操作控件的线程安全方法
- C# 跨线程操作控件的线程安全性方法
- C#跨线程操作控件的线程安全方法
- 工作线程操作UI线程元素的方法
- 线程服务ExecutorService的操作shutdown方法和shutdownNow方法
- Java 线程的基本概念 创建方法 和 基本操作
- 关于线程间操作无效的处理方法
- 关于线程间操作无效的处理方法
- 总结4种线程中操作UI界面的方法
- 4种线程中操作UI界面的方法
- 总结4种线程中操作UI界面的方法
- 总结4种线程中操作UI界面的方法
- 4种在线程中操作UI的方法
- 总结4种线程中操作UI界面的方法
- 解决grunt或者gulp 不是内部或者外部命令的问题
- JSP链接传参中文乱码
- 小红书欢迎引导界面第一版
- 关于springMVC 访问静态资源的问题
- eclipse 导入maven项目:Missing artifact jdk.tools:jdk.tools:jar:1.7
- 线程操作的方法
- QT之文本编辑器实现
- 【Java每日一题】20161107
- FragmentTabHost切换Fragment时避免UI重新加载
- [iOS]仿微博视频边下边播之封装播放器
- LocNet:Improving LocalizationAccuracy for Object Detection 随笔
- listView的item中含有checkbox的一些问题及解决办法
- laravel Carbon函数
- RNN资源博客 Recurrent Neural Network的经典论文、代码、课件、博士论文和应用汇总