多线程实现的细节---sleep和wait方法的区别、如何停止线程(interrupt方法)、守护线程(setDaemon())、join()方法、toString()方法、优先级、yield()方法

1.sleep和wait有什么区别?

sleep方法必须制定时间;wait方法有重载形式,可以指定时间,也可以不指定时间。

  • sleep方法

static void sleep(long millis):在执行的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。

static void sleep(long millis,int nanos):在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。

  • wait方法

wait()---在其他线程调用此对象的notify()方法活notifyAll()方法之前,导致当前线程等待。

wait(long timeout)-----在其他线程调用此对象的notify()方法活超过指定的时间量前,导致当前线程等待。

wait(long timeout,int nanos)------在其他线程调用此线程的notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。

对于执行权和锁的操作

  • sleep():

              释放执行权,因为如果不释放执行权,CPU只会处理当前休眠的线程,不能达到多线程操作的目的;

              不释放锁:因为线程肯定能唤醒,肯定可以恢复到临时阻塞状态。

  • wait()

             释放执行权

             释放锁:因为如果一个线程进入wait方法后不释放锁,如果没有时间指定,那么其他线程都进行不了同步中,无法将其唤醒。

 

同步中可以有多个存活的线程,但是只能有一个执行同步的代码。因为只有一个线程会持有同步的锁。

只有当该线程释放了锁,其他线程才有机会获取到锁,只能一个线程能够获取到锁,继续执行。

public synchronized void show()
{
    if()
        wait();


    code....;

    notify();

    code....;

}

例如线程A 进入同步方法,执行逻辑判断之后,wait()之后进入等待冻结状态,释放锁,释放执行权;只有释放锁,线程B才可以获取到锁进入同步方法show()中,线程B执行notify()之后,线程A被激活;此时存活的线程有线程A和线程B,但是只有线程B持有锁,所以只有线程B持有锁,只有线程B有CPU的执行权,所以只有线程B 会执行,只有当线程B执行wait()释放锁之后,线程A才会获得锁,才会进行执行。

 

如何让线程停止

 停止线程有两种方式:

1.使用Thread类中的stop方法,但是该方法已经过时了。

2.线程执行的代码结束,也就是run方法执行结束

    通常定义线程代码都有循环,因为需要单独开辟一个执行路径去重复很多事情,既然有循环,只要控制住循环,就可以结束run方法。

package Test.Test;

public class StopThreadDemo {
    public static void main(String[] args){
        StopThread st=new StopThread();
        Thread t1=new Thread(st);
        Thread t2=new Thread(st);
        t1.start();
        t2.start();
        int num=1;
        while(true){
            if(num++==5000){
                st.setFlag();
                break;
            }
            System.out.println(Thread.currentThread().getName()+"--------"+num);
        }
    }
}

class StopThread implements Runnable{

    private boolean flag=true;
    @Override
    public synchronized void run() {
         while(flag){
             System.out.println(Thread.currentThread().getName()+"------");
         }
    }

    public void setFlag() {
        this.flag = false;
    }
}

代码中开启了三个线程,当主线程执行num为500时,设置st的flag属性为false,主线程结束,两个子线程判断flag为false,run方法结束,两个子线程结束。

 

 interrupt方法

定义标记可以结束循环进而结束线程,但是如果子线程在运行过程中存储了冻结状态,没有执行到标记,这时子线程不能够正常结束,可以通过Thread类的interrupt方法中断线程的冻结状态,强制让其恢复到运行状态中来,就可以有机会执行标记,但是这种强制动作会发生InterruptedException异常,可以在catch住异常之后在异常处理块中修改标记,使子线程可以执行。

package Test.Test;

public class StopThreadDemo {
    public static void main(String[] args){
        StopThread st=new StopThread();
        Thread t1=new Thread(st);
        Thread t2=new Thread(st);
        t1.start();
        t2.start();
        int num=1;
        while(true){
            if(num++==5000){

                t1.interrupt();
                t2.interrupt();
                break;
            }
            System.out.println(Thread.currentThread().getName()+"--------"+num);
        }
    }
}

class StopThread implements Runnable{

    private boolean flag=true;
    @Override
    public synchronized void run() {
         while(flag){
             try{
                wait();
             }catch (InterruptedException e){
                 setFlag();
                 System.out.println(Thread.currentThread().getName()+".....Exception");
             }
             System.out.println(Thread.currentThread().getName()+"------");
         }
    }

    public void setFlag() {
        this.flag = false;
    }
}

 

守护线程

线程分前台和后台两种,运行方式都一样会获取cpu的执行权执行,不同在于结束方式不同。前台线程只有run方法结束才会结束,后台线程run方法结束会结束,还有一种结束方式是,如果run方法没有结束,而前台线程都结束了,后台线程一样会自动结束。

所以一个进程是否结束参考的是:是否还有前台线程存活,如果前台线程都结束了,那么进程也就结束了。

使用setDaemon(boolean on)如果传入参数为true将创建的线程转化为后台线程,该方法必须在启动线程前调用。

 

package Test.Test;

public class StopThreadDemo {
    public static void main(String[] args){
        StopThread st=new StopThread();
        Thread t1=new Thread(st);
        Thread t2=new Thread(st);
        t1.setDaemon(true);//将创建的线程转换为后台线程
        t2.setDaemon(true);
        t1.start();
        t2.start();
        int num=1;
        while(true){
            if(num++==5000){

                t1.interrupt();
                t2.interrupt();
                break;
            }
            System.out.println(Thread.currentThread().getName()+"--------"+num);
        }
    }
}

class StopThread implements Runnable{

    private boolean flag=true;
    @Override
    public synchronized void run() {
         while(flag){
             try{
                wait();
             }catch (InterruptedException e){
                 setFlag();
                 System.out.println(Thread.currentThread().getName()+".....Exception");
             }
             System.out.println(Thread.currentThread().getName()+"------");
         }
    }

    public void setFlag() {
        this.flag = false;
    }
}

 

Join方法,临时加入一个线程进行执行

例如:当主线程获取到了cpu的执行权,执行时,执行到了A线程的join方法,这时cpu的执行权在主线程持有,主线程会释放自己的执行权,让A线程进行执行。只有等待A线程执行完以后,主线程才会执行,在A线程执行的过程中主线程处于冻结状态。

一般使用情景:在线程执行过程中,需要一个运算结果时,可以通过加入一个临时线程,将该结果进行运算,这时需要的结果的线程处于冻结状态,等新加入的线程执行完原有的线程才会继续执行。

 

package Test.Test;

public class StopThreadDemo {
    public static void main(String[] args){
        StopThread st=new StopThread();
        Thread t1=new Thread(st);
        Thread t2=new Thread(st);
        t1.start();
        try{
            t1.join();
        }catch (InterruptedException e){}
        t2.start();

        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"------"+i);
        }
    }
}

class StopThread implements Runnable{


    @Override
    public synchronized void run() {
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"------"+i);
        }
    }
}

执行结果:主线程执行到t1.join()之后,主线程会让出执行权,直到t1执行完才会继续执行,执行结果如下,不太明白为什么t1和主线程没有抢占CPU执行权。

Thread-0------0
Thread-0------1
Thread-0------2
Thread-0------3
Thread-0------4
Thread-0------5
Thread-0------6
Thread-0------7
Thread-0------8
Thread-0------9
Thread-0------10
Thread-0------11
Thread-0------12
Thread-0------13
Thread-0------14
Thread-0------15
Thread-0------16
Thread-0------17
Thread-0------18
Thread-0------19
Thread-0------20
Thread-0------21
Thread-0------22
Thread-0------23
Thread-0------24
Thread-0------25
Thread-0------26
Thread-0------27
Thread-0------28
Thread-0------29
Thread-0------30
Thread-0------31
Thread-0------32
Thread-0------33
Thread-0------34
Thread-0------35
Thread-0------36
Thread-0------37
Thread-0------38
Thread-0------39
Thread-0------40
Thread-0------41
Thread-0------42
Thread-0------43
Thread-0------44
Thread-0------45
Thread-0------46
Thread-0------47
Thread-0------48
Thread-0------49
Thread-0------50
Thread-0------51
Thread-0------52
Thread-0------53
Thread-0------54
Thread-0------55
Thread-0------56
Thread-0------57
Thread-0------58
Thread-0------59
Thread-0------60
Thread-0------61
Thread-0------62
Thread-0------63
Thread-0------64
Thread-0------65
Thread-0------66
Thread-0------67
Thread-0------68
Thread-0------69
Thread-0------70
Thread-0------71
Thread-0------72
Thread-0------73
Thread-0------74
Thread-0------75
Thread-0------76
Thread-0------77
Thread-0------78
Thread-0------79
Thread-0------80
Thread-0------81
Thread-0------82
Thread-0------83
Thread-0------84
Thread-0------85
Thread-0------86
Thread-0------87
Thread-0------88
Thread-0------89
Thread-0------90
Thread-0------91
Thread-0------92
Thread-0------93
Thread-0------94
Thread-0------95
Thread-0------96
Thread-0------97
Thread-0------98
Thread-0------99
main------0
main------1
main------2
main------3
main------4
main------5
main------6
main------7
main------8
main------9
main------10
main------11
main------12
main------13
main------14
main------15
main------16
main------17
main------18
main------19
main------20
main------21
main------22
main------23
main------24
main------25
main------26
main------27
main------28
main------29
main------30
main------31
main------32
main------33
main------34
main------35
main------36
main------37
main------38
main------39
main------40
main------41
main------42
main------43
main------44
main------45
main------46
main------47
main------48
main------49
main------50
main------51
main------52
main------53
main------54
main------55
main------56
main------57
main------58
main------59
main------60
main------61
main------62
main------63
main------64
main------65
main------66
main------67
main------68
main------69
main------70
main------71
main------72
main------73
main------74
main------75
main------76
main------77
main------78
main------79
main------80
main------81
main------82
main------83
main------84
main------85
main------86
main------87
main------88
main------89
main------90
main------91
main------92
main------93
main------94
main------95
main------96
main------97
main------98
main------99
Thread-1------0
Thread-1------1
Thread-1------2
Thread-1------3
Thread-1------4
Thread-1------5
Thread-1------6
Thread-1------7
Thread-1------8
Thread-1------9
Thread-1------10
Thread-1------11
Thread-1------12
Thread-1------13
Thread-1------14
Thread-1------15
Thread-1------16
Thread-1------17
Thread-1------18
Thread-1------19
Thread-1------20
Thread-1------21
Thread-1------22
Thread-1------23
Thread-1------24
Thread-1------25
Thread-1------26
Thread-1------27
Thread-1------28
Thread-1------29
Thread-1------30
Thread-1------31
Thread-1------32
Thread-1------33
Thread-1------34
Thread-1------35
Thread-1------36
Thread-1------37
Thread-1------38
Thread-1------39
Thread-1------40
Thread-1------41
Thread-1------42
Thread-1------43
Thread-1------44
Thread-1------45
Thread-1------46
Thread-1------47
Thread-1------48
Thread-1------49
Thread-1------50
Thread-1------51
Thread-1------52
Thread-1------53
Thread-1------54
Thread-1------55
Thread-1------56
Thread-1------57
Thread-1------58
Thread-1------59
Thread-1------60
Thread-1------61
Thread-1------62
Thread-1------63
Thread-1------64
Thread-1------65
Thread-1------66
Thread-1------67
Thread-1------68
Thread-1------69
Thread-1------70
Thread-1------71
Thread-1------72
Thread-1------73
Thread-1------74
Thread-1------75
Thread-1------76
Thread-1------77
Thread-1------78
Thread-1------79
Thread-1------80
Thread-1------81
Thread-1------82
Thread-1------83
Thread-1------84
Thread-1------85
Thread-1------86
Thread-1------87
Thread-1------88
Thread-1------89
Thread-1------90
Thread-1------91
Thread-1------92
Thread-1------93
Thread-1------94
Thread-1------95
Thread-1------96
Thread-1------97
Thread-1------98
Thread-1------99

换一种方式:

package Test.Test;

public class StopThreadDemo {
    public static void main(String[] args){
        StopThread st=new StopThread();
        Thread t1=new Thread(st);
        Thread t2=new Thread(st);
        t1.start();
        t2.start();
        try{
            t1.join();
        }catch (InterruptedException e){}


        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"------"+i);
        }
    }
}

class StopThread implements Runnable{


    @Override
    public synchronized void run() {
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"------"+i);
        }
    }
}

执行结果为:

Thread-0------0
Thread-0------1
Thread-0------2
Thread-0------3
Thread-0------4
Thread-0------5
Thread-0------6
Thread-0------7
Thread-0------8
Thread-0------9
Thread-0------10
Thread-0------11
Thread-0------12
Thread-0------13
Thread-0------14
Thread-0------15
Thread-0------16
Thread-0------17
Thread-0------18
Thread-0------19
Thread-0------20
Thread-0------21
Thread-0------22
Thread-0------23
Thread-0------24
Thread-0------25
Thread-0------26
Thread-0------27
Thread-0------28
Thread-0------29
Thread-0------30
Thread-0------31
Thread-0------32
Thread-0------33
Thread-0------34
Thread-0------35
Thread-0------36
Thread-0------37
Thread-0------38
Thread-0------39
Thread-0------40
Thread-0------41
Thread-0------42
Thread-0------43
Thread-0------44
Thread-0------45
Thread-0------46
Thread-0------47
Thread-0------48
Thread-0------49
Thread-0------50
Thread-0------51
Thread-0------52
Thread-0------53
Thread-0------54
Thread-0------55
Thread-0------56
Thread-0------57
Thread-0------58
Thread-0------59
Thread-0------60
Thread-0------61
Thread-0------62
Thread-0------63
Thread-0------64
Thread-0------65
Thread-0------66
Thread-0------67
Thread-0------68
Thread-0------69
Thread-0------70
Thread-0------71
Thread-0------72
Thread-0------73
Thread-0------74
Thread-0------75
Thread-0------76
Thread-0------77
Thread-0------78
Thread-0------79
Thread-0------80
Thread-0------81
Thread-0------82
Thread-0------83
Thread-0------84
Thread-0------85
Thread-0------86
Thread-0------87
Thread-0------88
Thread-0------89
Thread-0------90
Thread-0------91
Thread-0------92
Thread-0------93
Thread-0------94
Thread-0------95
Thread-0------96
Thread-0------97
Thread-0------98
Thread-0------99
Thread-1------0
Thread-1------1
Thread-1------2
main------0
Thread-1------3
main------1
Thread-1------4
main------2
Thread-1------5
main------3
Thread-1------6
main------4
main------5
Thread-1------7
main------6
Thread-1------8
main------7
Thread-1------9
main------8
Thread-1------10
main------9
Thread-1------11
Thread-1------12
Thread-1------13
main------10
Thread-1------14
main------11
Thread-1------15
main------12
Thread-1------16
main------13
Thread-1------17
main------14
Thread-1------18
main------15
Thread-1------19
main------16
Thread-1------20
Thread-1------21
Thread-1------22
Thread-1------23
Thread-1------24
main------17
Thread-1------25
main------18
main------19
main------20
main------21
main------22
main------23
main------24
main------25
main------26
main------27
main------28
main------29
main------30
main------31
main------32
main------33
main------34
main------35
main------36
main------37
main------38
main------39
main------40
main------41
main------42
main------43
main------44
Thread-1------26
main------45
Thread-1------27
Thread-1------28
main------46
Thread-1------29
main------47
Thread-1------30
main------48
Thread-1------31
main------49
Thread-1------32
main------50
Thread-1------33
Thread-1------34
main------51
Thread-1------35
main------52
Thread-1------36
main------53
Thread-1------37
main------54
Thread-1------38
main------55
Thread-1------39
main------56
Thread-1------40
main------57
Thread-1------41
main------58
Thread-1------42
main------59
main------60
Thread-1------43
main------61
Thread-1------44
main------62
Thread-1------45
main------63
Thread-1------46
main------64
Thread-1------47
main------65
Thread-1------48
main------66
Thread-1------49
main------67
Thread-1------50
main------68
Thread-1------51
main------69
Thread-1------52
main------70
Thread-1------53
main------71
Thread-1------54
main------72
Thread-1------55
main------73
Thread-1------56
main------74
Thread-1------57
main------75
Thread-1------58
main------76
Thread-1------59
main------77
Thread-1------60
main------78
Thread-1------61
main------79
Thread-1------62
main------80
Thread-1------63
main------81
Thread-1------64
main------82
Thread-1------65
main------83
Thread-1------66
main------84
Thread-1------67
main------85
Thread-1------68
main------86
Thread-1------69
main------87
Thread-1------70
main------88
Thread-1------71
main------89
Thread-1------72
main------90
Thread-1------73
main------91
Thread-1------74
main------92
Thread-1------75
main------93
Thread-1------76
Thread-1------77
Thread-1------78
Thread-1------79
Thread-1------80
Thread-1------81
Thread-1------82
Thread-1------83
main------94
Thread-1------84
main------95
Thread-1------85
main------96
Thread-1------86
main------97
Thread-1------87
Thread-1------88
main------98
Thread-1------89
main------99
Thread-1------90
Thread-1------91
Thread-1------92
Thread-1------93
Thread-1------94
Thread-1------95
Thread-1------96
Thread-1------97
Thread-1------98
Thread-1------99

 

toString()

Thread类的toString方法返回该线程的字符串标识形式,包括线程名称、优先级和线程租Thread[Thread-0(线程名),5(优先级),main(所属线程组)]

 

优先级:

线程的优先级为1到10,每个相近的优先级之间其实没有太大差别,主要使用三个优先级 ,优先级高的线程在CPU执行权抢占的战斗中获胜的几率更大。

 

posted @ 2018-03-06 14:43  Garcia11  阅读(346)  评论(0)    收藏  举报