【大数据】学习笔记 1 Java SE 第9章 多线程 9.3 Thread类

【大数据】学习笔记

在这里插入图片描述

1 Java SE

第9章 多线程

9.3 Thread类
9.3.1 构造方法
  • public Thread() :分配一个新的线程对象。
  • public Thread(String name) :分配一个指定名字的新的线程对象。
  • public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
  • public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。
9.3.2 常用方法系列1
  • public void run() :此线程要执行的任务在此处定义代码。

  • public String getName() :获取当前线程名称。

  • public static Thread currentThread() :返回对当前正在执行的线程对象的引用。

  • public final boolean isAlive():测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。

  • public final int getPriority() :返回线程优先级

  • public final void setPriority(int newPriority) :改变线程的优先级

    • 每个线程都有一定的优先级,优先级高的线程将获得较多的执行机会。每个线程默认的优先级都与创建它的父线程具有相同的优先级。Thread类提供了setPriority(int newPriority)和getPriority()方法类设置和获取线程的优先级,其中setPriority方法需要一个整数,并且范围在[1,10]之间,通常推荐设置Thread类的三个优先级常量:
    • MAX_PRIORITY(10):最高优先级
    • MIN _PRIORITY (1):最低优先级
    • NORM_PRIORITY (5):普通优先级,默认情况下main线程具有普通优先级。
	public static void main(String[] args) {
    
    
		Thread t = new Thread(){
    
    
			public void run(){
    
    
				System.out.println(getName() + "的优先级:" + getPriority());
			}
		};
		t.setPriority(Thread.MAX_PRIORITY);
		t.start();
		
		System.out.println(Thread.currentThread().getName() +"的优先级:" + Thread.currentThread().getPriority());
	}
9.3.3 常用方法系列2
  • public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。

  • public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。

  • public static void yield():yield只是让当前线程暂停一下,让系统的线程调度器重新调度一次,希望优先级与当前线程相同或更高的其他线程能够获得执行机会,但是这个不能保证,完全有可能的情况是,当某个线程调用了yield方法暂停之后,线程调度器又将其调度出来重新执行。

  • void join() :等待该线程终止。

    void join(long millis) :等待该线程终止的时间最长为 millis 毫秒。如果millis时间到,将不再等待。

    void join(long millis, int nanos) :等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。

package com.dingjiaxiong.api;

/**
 * @Projectname: BigDataStudy
 * @Classname: TestThreadStateChange
 * @Author: Ding Jiaxiong
 * @Date:2023/4/27 15:53
 */

public class TestThreadStateChange {
    
    
    public static void main(String[] args) {
    
    
        Thread te = new Thread() {
    
    
            @Override
            public void run() {
    
    
                for (int i = 2; i <= 100; i += 2) {
    
    
                    System.out.println("偶数线程:" + i);
                    try {
    
    
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        };
        te.start();

        Thread to = new Thread() {
    
    
            @Override
            public void run() {
    
    
                for (int i = 1; i <= 100; i += 2) {
    
    
                    System.out.println("奇数线程:" + i);
                    if (i == 5) {
    
    
//                        Thread.yield();
                        try {
    
    
                            te.join();
                        } catch (InterruptedException e) {
    
    
                            e.printStackTrace();
                        }
                    }

                }
            }
        };
        to.start();
    }
}

运行效果

在这里插入图片描述

9.3.4 如何让线程提前结束

一个线程如何让另一个线程提前结束呢?

线程的死亡有两种:

自然死亡:当一个线程的run方法执行完,线程自然会停止。

意外死亡:当一个线程遇到未捕获处理的异常,也会挂掉。

我们肯定希望是让线程自然死亡更好。

  • public final void stop():强迫线程停止执行。 该方法具有固有的不安全性,已经标记为@Deprecated==(已过时、已废弃)==不建议再使用,那么我们就需要通过其他方式来停止线程了,其中一种方式是使用变量的值的变化来控制线程是否结束。

  • 标记法

案例:

声明一个PrintEvenThread线程类,继承Thread类,重写run方法,实现打印[1,100]之间的偶数,要求每隔1毫秒打印1个偶数。

声明一个PrintOddThread线程类,继承Thread类,重写run方法,实现打印[1,100]之间的奇数。

在main线程中:

(1)创建两个线程对象,并启动两个线程

(2)当打印奇数的线程结束了,让偶数的线程也停下来,就算偶数线程没有全部打印完[1,100]之间的偶数。

package com.dingjiaxiong.api;

/**
 * @Projectname: BigDataStudy
 * @Classname: PrintEvenThread
 * @Author: Ding Jiaxiong
 * @Date:2023/4/27 15:54
 */

public class PrintEvenThread extends Thread {
    
    
    private boolean flag = true;

    @Override
    public void run() {
    
    
        for (int i = 2; i <= 100 && flag; i += 2) {
    
    
            System.out.println("偶数线程:" + i);
            try {
    
    
                Thread.sleep(1);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }

    public void setFlag(boolean flag) {
    
    
        this.flag = flag;
    }
}
package com.dingjiaxiong.api;

/**
 * @Projectname: BigDataStudy
 * @Classname: PrintOddThread
 * @Author: Ding Jiaxiong
 * @Date:2023/4/27 15:54
 */

public class PrintOddThread extends Thread {
    
    
    @Override
    public void run() {
    
    
        for (int i = 1; i <= 100; i += 2) {
    
    
            System.out.println("奇数线程:" + i);
        }
    }
}

测试类

package com.dingjiaxiong.api;

/**
 * @Projectname: BigDataStudy
 * @Classname: TestThreadStop
 * @Author: Ding Jiaxiong
 * @Date:2023/4/27 15:55
 */

public class TestThreadStop {
    
    
    public static void main(String[] args) {
    
    
        PrintEvenThread pe = new PrintEvenThread();
        PrintOddThread po = new PrintOddThread();
        pe.start();
        po.start();

        try {
    
    
            po.join();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        pe.setFlag(false);
    }
}

运行结果

在这里插入图片描述

9.3.5 守护线程(了解)

有一种线程,它是在后台运行的,它的任务是为其他线程提供服务的,这种线程被称为“守护线程”。JVM的垃圾回收线程就是典型的守护线程。

守护线程有个特点,就是如果所有非守护线程都死亡,那么守护线程自动死亡。

调用setDaemon(true)方法可将指定线程设置为守护线程。必须在线程启动之前设置,否则会报IllegalThreadStateException异常。

调用isDaemon()可以判断线程是否是守护线程。

package com.dingjiaxiong.api;

/**
 * @Projectname: BigDataStudy
 * @Classname: TestThread
 * @Author: Ding Jiaxiong
 * @Date:2023/4/27 15:55
 */

public class TestThread {
    
    
    public static void main(String[] args) {
    
    
        MyDaemon m = new MyDaemon();
        m.setDaemon(true);
        m.start();

        for (int i = 1; i <= 100; i++) {
    
    
            System.out.println("main:" + i);
        }
    }
}

class MyDaemon extends Thread {
    
    
    public void run() {
    
    
        while (true) {
    
    
            System.out.println("我一直守护者你...");
            try {
    
    
                Thread.sleep(1);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述

练习:龟兔赛跑

案例:编写乌龟类(Tortoise)和兔子类(Rabbit), 编写龟兔赛跑多线程程序,设赛跑长度为30米。乌龟和兔子每跑完10米输出一次结果。

  • 兔子的速度是10米每秒,兔子每跑完10米休眠的时间10秒。
  • 乌龟的速度是1米每秒,乌龟每跑完10米的休眠时间是1秒。

案例完成思路要求:
乌龟定义一个线程,兔子定义一个线程,两个线程同时开启,提示:可以使用Thread.sleep(毫秒数)来模拟耗时。

package com.dingjiaxiong;

/**
 * @Projectname: BigDataStudy
 * @Classname: TortoiseAndRabbitTest
 * @Author: Ding Jiaxiong
 * @Date:2023/4/27 15:57
 */

public class TortoiseAndRabbitTest {
    
    

    public static void main(String[] args) {
    
    
        Tortoise t = new Tortoise();
        Rabbit r = new Rabbit();
        new Thread(t).start();
        new Thread(r).start();
    }

}

class Tortoise implements Runnable {
    
    

    @Override
    public void run() {
    
    
        for (int i = 1; i <= 30; i++) {
    
    //i代表米数,每次+1代表跑过了一米。
            try {
    
    
                Thread.sleep(1000);//每次循环休眠1一秒,代表一秒钟跑了一米
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("乌龟跑了一米~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            if (i == 30) {
    
    
                System.out.println("乌龟跑到了终点=============================");
                break;
            }
            if (i % 10 == 0) {
    
    
                try {
    
    
                    Thread.sleep(1000);//每隔十米乌龟要休眠一秒
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

}


class Rabbit implements Runnable {
    
    

    @Override
    public void run() {
    
    
        // TODO Auto-generated method stub
        for (int i = 1; i <= 30; i++) {
    
    //i代表米数,每次+1代表跑过了一米。
            try {
    
    
                Thread.sleep(100);//每次循环休眠0.1一秒,代表一秒钟跑了十米
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("兔子跑了一米~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            if (i == 30) {
    
    
                System.out.println("兔子跑到了终点=============================");
                break;
            }
            if (i % 10 == 0) {
    
    
                try {
    
    
                    Thread.sleep(10000);//每隔十米兔子要休眠是秒
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44226181/article/details/130480134
今日推荐