• Java之线程相关应用实现


    后台线程

    一个进程中只有后台进程运行,该进程将会结束。

    新创建的线程默认为前台线程,Java中只要有一个前台线程运行,就不会结束程序,如果只有后台线程运行,程序就会结束,可以在线程对象启动前执行setDaemon(true)语句设置该线程为后台线程。

    1. class Main {
    2. public static void main(String[] args) {
    3. System.out.println("main()线程是后台线程吗"+Thread.currentThread().isDaemon());
    4. DaemonThread daemon=new DaemonThread();
    5. Thread thread=new Thread(daemon,"后台线程");
    6. System.out.println("Daemons是后台线程吗"+thread.isDaemon());
    7. thread.setDaemon(true);//设置为后台线程
    8. System.out.println("Daemons是后台线程吗"+thread.isDaemon());
    9. thread.start();
    10. //模拟主线程main执行
    11. int i=0;
    12. for(;i<3;i++){
    13. System.out.println(i);
    14. }
    15. }
    16. }
    17. class DaemonThread implements Runnable {
    18. //模拟分线程执行
    19. public void run(){
    20. while(true){
    21. System.out.println(Thread.currentThread().getName()+"正在运行");
    22. }
    23. }
    24. }

    657dcc7e398d43e38c6b0ba9dc153ec7.png

    线程的优先级

    使用setPriority方法,设置优先级为1到10;数字越大,优先级越高,获得CPU的使用权机会越大。

    1. class Main {
    2. public static void main(String[] args) {
    3. Thread minPriority =new Thread(new maxpriority(),"优先级较高线程");
    4. Thread maxPriority=new Thread(new minpriority(),"优先级较低线程");
    5. minPriority.setPriority(Thread.MIN_PRIORITY);//设置优先级为1
    6. maxPriority.setPriority(Thread.MAX_PRIORITY);//设置优先级为10
    7. //开启两个线程
    8. minPriority.start();
    9. maxPriority.start();
    10. }
    11. }
    12. class maxpriority implements Runnable{
    13. public void run(){
    14. for(int i=0;i<3;i++) {
    15. System.out.println(Thread.currentThread().getName() + "正在输出" + i);
    16. }
    17. }
    18. }
    19. class minpriority implements Runnable{
    20. public void run(){
    21. for(int i=0;i<3;i++) {
    22. System.out.println(Thread.currentThread().getName() + "正在输出" + i);
    23. }
    24. }
    25. }

    82ba89d33e6e405e95cba44fcd8189dd.png

    线程休眠

    当前线程暂停运行,进入阻塞状态哦使用sleep()方法。传入参数单位为毫秒。

    sleep调用时,只能让当前正在运行的线程休眠,

    1. class Main {
    2. public static void main(String[] args) {
    3. new Thread(new Sleepthread()).start();//开启新线程
    4. for(int i=1;i<=8;i++){
    5. try{ if(i==5){
    6. Thread.sleep(1000);
    7. }
    8. System.out.println("主线程正在输出"+i);
    9. Thread.sleep(500);}
    10. catch(InterruptedException e){
    11. e.printStackTrace();
    12. }
    13. }
    14. }
    15. }
    16. class Sleepthread implements Runnable{
    17. public void run(){
    18. for(int i=1;i<=8;i++){
    19. if(i==3){
    20. try{
    21. Thread.sleep(1000);
    22. }catch(Exception e){
    23. e.printStackTrace();
    24. }
    25. }
    26. System.out.println("Sleep线程正在输出"+i);
    27. try{ Thread.sleep(500);}
    28. catch(Exception e){
    29. e.printStackTrace();
    30. }
    31. }
    32. }
    33. }

    72f75bcac65e4cd098521426f08758bf.png

    主线程在Sleep线程输出3之前连续输出2,3,4;说明此时Sleep线程在输出值3时先休眠了一段时间;

    另外,Sleep线程再输出6之前,主线程也连续输出5,6;说明此时Sleep在输出6时休眠了一段时间。

    线程插队

    1. class Main {
    2. public static void main(String[] args) throws Exception {
    3. Thread thread=new Thread(new Joinrunable(),"thread");
    4. thread.start();
    5. for(int i=1;i<=4;i++){
    6. if(i==2){
    7. thread.join();//调用join()方法插队实现
    8. }
    9. System.out.println(Thread.currentThread().getName()+"线程正在输出"+i);
    10. }
    11. }
    12. }
    13. class Joinrunable implements Runnable{
    14. public void run(){
    15. for(int i=1;i<=3;i++){
    16. System.out.println(Thread.currentThread().getName()+"线程正在输出"+i);
    17. }
    18. }
    19. }

    main()线程和thread线程互相争夺CPU使用权,然后当i=3时候

    711040d214f34ed2acffaabc7efe4b8f.png

    线程生命周期的六种基本状态

    (1)新建状态

    创建一个线程对象后,还没有调用start()方法启动之前的状态

    (2)可运行状态

    就绪状态,调用了start()方法之后进入的状态。

    (3)锁阻塞状态

    当一个线程想要获取一个对象锁,该aii锁被其他线程持有,该线程进入锁阻塞状态。

    (4)无限等待状态

    一个线程等待另一个线程执行一个唤醒动作,该线程进入的状态。

    (5)计时等待状态

    具有指定等待时间的状态,一直保持到超时或被唤醒

    (6)被终止状态

    终止运行,由于正常退出或者异常没有被捕获而结束。

    线程让步

    某个特定时间点,线程暂停抢夺CPU,采用yield()方法实现。

    1. class Main {
    2. public static void main(String[] args) throws Exception {
    3. //新建两个线程
    4. Thread th1=new Fieldthread("th1");
    5. Thread th2=new Fieldthread("th2");
    6. //开启两个线程
    7. th1.start();
    8. th2.start();
    9. }
    10. }
    11. class Fieldthread extends Thread {
    12. public Fieldthread(String name) {
    13. super(name);//调用父类带参构造方法
    14. }
    15. public void run() {
    16. for(int i=1;i<4;i++){
    17. System.out.println(Thread.currentThread().getName()+"线程输出"+i);
    18. if(i==2){
    19. System.out.println("线程让步");
    20. //线程让步
    21. Thread.yield();
    22. }
    23. }
    24. }
    25. }

    2b1eac01d6a24dea91c6889045062b69.png

    线程中断

    调用两种方法实现:

    interrupt()方法和isInterrupted()方法

    isInterrupted方法判断中断标志位,如果为真表示中断。

    1. class Main {
    2. public static void main(String[] args) throws Exception {
    3. Thread thread=new Thread(
    4. new Runnable() {
    5. public void run() {
    6. for (int i = 0; i < 4; i++) {
    7. if(i==2){
    8. Thread.currentThread().interrupt();
    9. System.out.println("线程是否中断"+Thread.currentThread().isInterrupted());
    10. }
    11. }
    12. }
    13. }
    14. );//创建实例对象
    15. thread.start();//启动线程
    16. }
    17. }

    e3190bf4c7c54f79b853a47a30295c46.png

    线程同步

    1. class Main {
    2. public static void main(String[] args) throws Exception {
    3. Salethread salethread = new Salethread();
    4. new Thread((salethread),"线程1").start();//创建并启动新线程
    5. new Thread((salethread),"线程2").start();//创建并启动新线程
    6. new Thread((salethread),"线程3").start();//创建并启动新线程
    7. }
    8. }
    9. class Salethread implements Runnable{
    10. private int tickets=10;
    11. public void run(){
    12. while(tickets>0){
    13. try{
    14. Thread.sleep(300);
    15. }catch(Exception e){
    16. e.printStackTrace();
    17. }
    18. System.out.println(Thread.currentThread().getName()+"卖出票号是 "+tickets--);
    19. }
    20. }
    21. }

    2b0ba6ab35a341238fa1692dfe1ad67c.png

    结果的票数中出现了0;之所以这样是因为每个线程都会先调用sleep方法进入休眠一段时间。即假设票数为3时候,线程2先进入while循环,然后调用sleepf方法休眠一段时间,在此期间票数值不变,因为票数只有在最后输出时候才会减少,线程3进入while循环,然后调用sleep()方法休眠一段时间,于此同时然后线程1进入while循环,然后调用sleep()方法进入休眠,最后三个线程依次结束休眠状态,相继售票,即票数由3变化到0;

    所以为了安全起见,使用同步代码块,使得多线程访问处理同一资源时候,任何时刻只能由一个线程访问处理。

    将共享资源的代码放在synchronized(lock)关键字修饰的代码块中。

    synchronized(lock){

    处理共享资源的代码块

    }

    lock是指锁,即某个线程执行时,其他线程不能执行。

    1. class Main {
    2. public static void main(String[] args) throws Exception {
    3. Salethread salethread = new Salethread();
    4. new Thread((salethread),"线程1").start();//创建并启动新线程
    5. new Thread((salethread),"线程2").start();//创建并启动新线程
    6. new Thread((salethread),"线程3").start();//创建并启动新线程
    7. }
    8. }
    9. class Salethread implements Runnable{
    10. private int tickets=10;
    11. Object lock=new Object();//定义锁
    12. public void run(){
    13. while(tickets>0){
    14. synchronized (lock) { try{
    15. Thread.sleep(300);
    16. }catch(Exception e){
    17. e.printStackTrace();
    18. }
    19. if(tickets>0){ System.out.println(Thread.currentThread().getName()+"卖出票号是 "+tickets--);}
    20. else{
    21. break;
    22. }}
    23. }
    24. }
    25. }

    f01c0b6c07384ee580bb81a3934cbf28.png

    同步方法

     

  • 相关阅读:
    Java 入门基础知识
    测试和开发的日常互撕,真的不能好好解决嘛?
    Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢
    “高级小程序开发指南“
    职场PUA:为什么你就不能逼自己一把呢?
    基于微信小程序的在线测试系统
    docker镜像与容器基本的基本操作(三)
    HLS入门
    TortoiseGit间接处理linux目录下的仓库,用到window映射linux目录方案
    python3读写dbf文件
  • 原文地址:https://blog.csdn.net/2302_77397775/article/details/139998899