zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【JAVA】常见的几种线程运行机制 及 特殊线程 ——线程让步、线程加入(线程合并)、线程的优先级、中断线程、守护线程(精灵线程)

JAVA线程 常见 几种 合并 加入 中断 特殊
2023-09-11 14:20:37 时间

Thread.yeild()

 Thread.yeild()是线程让步,即让当前处于运行状态的线程回到就绪状态,将剩余的时间让出来。

 但是,在线程运行机制里,没有哪一个方法能精确执行某项操作,只能是模糊执行。

package edu.xalead;

class TH1 extends Thread {

    *这里我们要知道的是,线程本身是有名字的。
    *是从Thread类里面继承下来的。
    *所以我们就不用在写名字了,虚拟机会默认分配一个名字。
    
    TH1() {

        this.setName( "让步线程" );
    }

    @Override
    public void run() {
        while (true) {
            Thread.yield();
            System.out.println( this.getName() );

        }
    }
}

class TH2 implements Runnable {
    
    *由于Runnable接口里面只有一个run()方法,
    *所以,这里输出里面直接填this.getName()会报错。
    *这里,我们可以用线程里头的Thread.currentThread().getName(),
    *这是得到当前正在运行的线程的接口的实现类里头的属性的。
    
    @Override
    public void run() {
        while (true) {
            System.out.println( Thread.currentThread().getName() );
            Thread.yield();
        }
    }
}

public class 让步 {
    public static void main(String[] args) {
        TH1 t = new TH1();
        t.start();
        TH2 th = new TH2();
        
        *TH2因为没有Thread类,就没有Run方法。
        *我们就可以用将节口的规范传到创建的Thread对象里头去,
        *取实现Runnable()方法。
        
        Thread t1 = new Thread(th);
        t1.start();
    }
}

 

Thread.jion()

Thread.jion()称为线程加入,是让要加入运行行列的线程先运行。而之前启动该线程的线程,则退出运行状态,处于阻塞状态。与Thread.sleep()的区别就是,Thread.sleep()阻塞的是该线程自己,Thread.jion()阻塞的是启动该线程的线程。且jion()方法将t线程加入到了启动这个线程的线程里头了, 这样,这两个线程就合并成了一个单线程。 所以,jion()又叫线程合并。 且主线程得要等t线程执行完才能执行

package edu.xalead;

class TTT1 implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println( Thread.currentThread().getName() );
        }
    }
}

public class 加入 {
    public static void main(String[] args) throws InterruptedException {
//        new Thread( new TTT1() ).start();
//        或者
//        Thread t=new Thread( new TTT1() );
//        t.start();

        //这里主线程和子线程是交替执行的。
        //交替时间大体各占50%

        Thread t = new Thread( new TTT1() );
        t.start();
        t.join();
//        jion()方法将t线程加入到了启动这个线程的线程理由了,
//        这样,这两个线程就合并成了一个单线程。
//        所以,jion()又叫线程合并。
//        且主线程得要等t线程执行完才能执行。

        while (true) {
            System.out.println( Thread.currentThread().getName() );
        }
    }
}

 

线程的优先级

           级别                                                   级数

1、最大优先级: t1.setPriority( Thread.MAX_PRIORITY );     (10)
2、最小优先级: t2.setPriority( Thread.MIN_PRIORITY );     (1)
3、普通优先级: t3.setPriority( Thread.NORM_PRIORITY );    (5)

这里,对线程的优先级,我们做的是对执行时间的分配的调整。这在之前,三个线程是平均分配执行时间的。

且优先级要在程序执行之前设置,不然不管用。

package edu.xalead;

class TS implements Runnable{
    @Override
    public void run(){
        while(true){
            System.out.println(Thread.currentThread().getName());
        }
    }
}

public class 线程的优先级 {
    public static void main(String[] args) {
        Thread t1=new Thread( new TS(),"A" );
        Thread t2=new Thread( new TS(),"B" );
        Thread t3=new Thread( new TS(),"C");
        //优先级要在程序执行之前设置。
        t1.setPriority( Thread.MAX_PRIORITY );
        t2.setPriority( Thread.MIN_PRIORITY );
        t3.setPriority( Thread.NORM_PRIORITY );
        t1.start();
        t2.start();
        t3.start();
    }
}

 

t.setDaemon( true)

t.setDaemon(true)叫作守护线程,又叫灵线程同样,守护线程的设置也应该在程序启动之前设置,才起作用。这里,守护线程是无线循环执行的。且守护线程如果是由主线程启动的,当主线程执行完了,守护线程也就执行结束了。也就是说,只要是哪个线程启动守护线程的,守护线程就等待哪个线程的执行。

如果不是主线程启动的,只要主线程一结束,尽管守护线程守护的不是主线程,但是守护线程也就结束了。

守护线程往往是给主线程扫除障碍的,比如服务器的面临可能会崩溃的情况,守护线程会替主线程监视服务器的运行情况

package edu.xalead;

class TSS implements Runnable {
    /**
     * 普通线程
     */
    @Override
    public void run() {
        Thread t2 = new Thread( new TSS(), "aaa" );
        t2.start();
        System.out.println( Thread.currentThread().getName() );
    }
}

public class 守护线程 {
    public static void main(String[] args) {
        /**
         * 守护线程无线循环执行
         */
        Thread t1 = new Thread( new TSS() );
        t1.setDaemon( true );//设置守护线程
        //主线程执行,守护线程就会开始执行。
        t1.start();


        /**
         * 主线程有限循环执行
         */
        for (int i = 0; i < 1000; i++) {
            System.out.println( Thread.currentThread().getName() );
        }
    }
}

 

中断线程

t.interrupt()为中断线程,不过我们要注意的是。t.interrupt()只是改变状态,是在线程运行状态中进行操作的。而中断的操作是由

if(this.isInterrupted()){
    break;
}

while (System.currentTimeMillis() < tt + 10000) {
        t.interrupt();
}

来控制的。

拓展:

【二者有个共同的问题——有死锁倾向

t.suspend()  挂起,即把线程执行的时间让出处,一直等线程恢复的时候,在执行。

t.resume()  线程恢复

有断掉数据库连接的特性
t.stop()  会断掉数据库服务器连接,数据库服务器会保留这个连接。也就相当于打开了一个没有用的连接,对服务器的运行有很大的影响。】

package edu.xalead;

class TTTT extends Thread{
    public void run(){
        try {
            while(true){
                System.out.println(this.isInterrupted());

                /**
                 * 杀死线程的代码
                 */
                if(this.isInterrupted()){
                    break;
                }

                System.out.println(Thread.currentThread().getName());
                //Thread.sleep( 1000 );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class 中断线程 {
    public static void main(String[] args) {
        TTTT t = new TTTT();
        t.start();

        try {
            Thread.sleep( 10000 );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       
        long tt = System.currentTimeMillis();
        while (System.currentTimeMillis() < tt + 10000) {
                t.interrupt();
        }
    }
}