终止线程

如果我们想在一个线程中终止另一个线程我们一般不使用 JDK 提供的 stop()/destroy() 方法(它们本身也被 JDK 废弃了)。通常的做法是提供一个 boolean 型的终止变量,当这个 变量值为 false时,则终止线程的运行。

  1. import java.io.IOException;
  2. public class StopThreadTest implements Runnable{
  3. private boolean flag=true;
  4. /**
  5. * 线程体方法
  6. */
  7. @Override
  8. public void run() {
  9. System.out.println(Thread.currentThread().getName()+"线程开始");
  10. int i=0;
  11. while(flag){
  12. System.out.println(Thread.currentThread().getName()+" "+i++);
  13. try{
  14. Thread.sleep(1000);
  15. }catch(Exception e){
  16. e.printStackTrace();
  17. }
  18. }
  19. System.out.println(Thread.currentThread().getName()+"线程结束");
  20. }
  21. public void stop(){
  22. this.flag=false;
  23. }
  24. public static void main(String[] args) {
  25. System.out.println("主线程开始");
  26. StopThreadTest stopThreadTest=new StopThreadTest();
  27. Thread t1=new Thread(stopThreadTest);
  28. t1.start();
  29. try {
  30. System.in.read();
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. }
  34. stopThreadTest.stop();
  35. System.out.println("主线程结束");
  36. }
  37. }

暂停当前线程执行sleep/yield

暂停线程执行常用的方法有 sleep()和 yield()方法,这两个方法的区别是:
sleep()方法:可以让正在运行的线程进入阻塞状态,直到休眠时间满了,进入就绪状 态。
看上面的例子

yield()方法:

可以让正在运行的线程直接进入就绪状态,让出 CPU 的使用权。

  1. yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。 <br />yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用 yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。 但是,实际中无法保证 yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中 <br />使用 yield 方法时要注意的几点:
  • yield 是一个静态的方法。
  • 调用 yield 后,yield 告诉当前线程把运行机会交给具有相同优先级的线程。
  • yield 不能保证,当前线程迅速从运行状态切换到就绪状态
  • yield 只能是将当前线程从运行状态转换到就绪状态,而不能是等待或者阻塞状态。
public class YieldThreadDemo implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            if("Thread-0".equals(Thread.currentThread().getName())){
                if(i==0){
                    Thread.yield();  //这里可以看出,yieal是个静态方法,直接类调用
                }
            }
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
    }

    public static void main(String[] args) {
        Thread t1=new Thread(new YieldThreadDemo());
        Thread t2=new Thread(new YieldThreadDemo());

        t1.start();
        t2.start();
    }
}

线程的联合

当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结束之前,当前线程不 能再次执行。线程 A 在运行期间,可以调用线程 B 的 join()方法,让线程 B 和线程 A 联合。 这样,线程 A 就必须等待线程 B 执行完毕后,才能继续执行

join方法的使用

join()方法就是指调用该方法的线程在执行完 run()方法后,再执行 join 方法后面的代码, 即将两个线程合并,用于实现同步控制

public class JoinThreadDemo {
    public static void main(String[] args) {
    Thread threadA=new Thread(new A());
    Thread threadB=new Thread(new B());
    threadA.start();
    threadB.start();
    for(int i=0;i<10;i++){
        System.out.println(Thread.currentThread().getName()+" "+i);
        if(i==2){
            try {
                threadA.join();  //想要联合谁,就用对方对象调用join()方法,相当于对方加入进来
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    }
}

class A implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+" "+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 class B implements Runnable{
     @Override
     public void run() {
         for(int i=0;i<10;i++){
             System.out.println(Thread.currentThread().getName()+" "+i);
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
 }

image.png

线程联合案例

public class JoinDemo2 {
    public static void main(String[] args) {
        System.out.println("女朋友让男朋友买奶茶的故事");
        Thread girlThread=new Thread(new Girl());
        girlThread.start();
    }
}

class Girl implements Runnable{
    @Override
    public void run() {
        System.out.println("女朋友想喝奶茶");
        System.out.println("女朋友让男朋友去买一杯沽名");
        Thread boyThread=new Thread(new Boy());
        boyThread.start();
        System.out.println("等待男朋友带奶茶回来");
        try {
            boyThread.join();
        } catch (InterruptedException e) {
            System.out.println("时间太长,打电话催一下");
            e.printStackTrace();
        }
        System.out.println("男朋友带奶茶回来了,给她一个吻");
    }
}

class  Boy implements Runnable{
    @Override
    public void run() {
        System.out.println("男朋友出门买奶茶");
        System.out.println("男朋友买奶茶要10分钟");
        for(int i=0;i<10;i++){
            System.out.println("第"+i+"分钟");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("男朋友买奶茶回来了");
    }
}

image.png

Thread类中的其他常用方法

获取当前线程名称

public class GetName_1 extends Thread{
    @Override
    public void run() {
        System.out.println(this.getName());
    }
}
class GetName_2 implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

设置线程名称

class SetName_1 extends Thread{
    public SetName_1(String name){
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.getName());
    }
}

public class SetName {
    public static void main(String[] args) {
        SetName_1 setName_1=new SetName_1("耿");
        setName_1.start();
    }
}
class SetName_2 implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

public class SetNameDemo_2 {
    public static void main(String[] args) {
        Thread thread=new Thread(new SetName_2());
        thread.setName("龙");
        thread.start();
    }
}

判断当前线程是否存活

isAlive()方法: 判断当前的线程是否处于活动状态。
活动状态是指线程已经启动且尚未终止,线程处于正在运行或准备开始运行的状态,就 认为线程是存活的

public class AliveDemo {
    public static void main(String[] args) {
        Thread aliveThread=new Thread(new Alive());
        System.out.println(aliveThread.isAlive()+"2");
        aliveThread.start();
        System.out.println(aliveThread.isAlive()+"3");
        try{
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(aliveThread.isAlive()+"4");
    }
}

class Alive implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().isAlive()+"1");
        try{
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}