线程操作的方法

来源:互联网 发布:h3c s7506e 端口聚合 编辑:程序博客网 时间:2024/06/14 15:23

从线程状态 的图中可以发现,在Java实现多线程的程序中,虽然Thread类实现了Runnable接口,但是操作线程的主要方法并不在Runnable接口中,而是在Thread类中。

Thread类中主要方法

方法名称 类型 概述 public Thread(Runnable target) 构造 接收Runnable接口子类对象,实例化Thread对象 public Thread(Runnable target,String name) 构造 接收Runnable接口子类对象,实例化Thread对象,并设置线程名称 public void run() 普通 执行线程 。。。。 。。 。。。。 public final void setDemo(boolean on) 普通 将一个线程设置成后台运行

下面介绍几种常用的线程操作方法。

  1. 取得和设置线程的名称
    在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的线程操作中,所有的线程在运行前都会保持在就绪状态,那么此时,哪个线程的优先级高,哪个线程就可能会先被执行。
线程的优先级:

Created with Raphaël 2.1.0MIN_PRIORITYNORM_PRIORITYMAX_PRIORITY

优先级越高,越有可能先执行。
在Java的线程中使用setPriority()方法可以设置一个线程的优先级,在Java的线程中一共有3中优先级:

定义 描述 表示的常量 public static final MIN_PRIORITY 最低优先级 1 public static final NORM_PRIORITY 中等优先级,线程的默认优先级 5 public static final MAX_PRIORITY 最高优先级 10

不同优先级的线程执行结果。
【测试线程优先级】

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),就会将本线程暂停,而让其他线程先执行。

好了,以上就是线程常用的几种操作了。

1 0
原创粉丝点击