补充:一些常见方法以及第一阶段总结

目录

pork与Interrupted()方法

 练习2

守护线程

线程状态: 

例子:洗茶壶(多线程处理问题)

小结:


pork与Interrupted()方法

pork:终止线程,下面的不再运行,其实就是根据线程状态来的,如果为true就可以往下执行

Thread.interrupted():将线程状态设置为反

思路:我们先进行对线程t1的终止,之后主线程运行使用Interrupt方法打断线程,导致可以继续t1线程的运行,此时状态为true,输出repark后,我们利用Interrupted()方法将状态设置为反也就是false,那么此时再遇到park()方法时将不能往下执行;

package com.example.juc.Test;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.LockSupport;

import static java.lang.Thread.sleep;

/**
 * @author diao 2022/4/1
 */
@Slf4j(topic = "c.ParkTest02")
public class ParkTest02 {
    public static void main(String[] args) throws InterruptedException {
        test();
    }

    private static void test() throws InterruptedException {
       log.debug("main");
        Thread t1 = new Thread(() -> {
            log.debug("park...");
            //打断,park终止
            LockSupport.park();
            log.debug("repark..");
            //打断状态,并利用interrupted将状态设置为反
            log.debug("打断状态:{}", Thread.interrupted());

            LockSupport.park();
            log.debug("怎么进来了");
        });
       t1.start();

       sleep(10);
       //主线程睡10ms后打断t1线程,使其能够继续往下执行
        t1.interrupt();
        System.out.println(t1.isInterrupted());
    }
}

 练习2

  public static void test2() throws InterruptedException {
        log.debug("main..");
        Thread t2=new Thread(()->{
            log.debug("begin..");
            LockSupport.park();
            log.debug("continue...");
        });
        t2.start();

        //查看t2线程状态
        log.debug(String.valueOf(t2.isInterrupted()));
        Thread.sleep(10);
        log.debug(String.valueOf(t2.isInterrupted()));
    }


stop我们可以用Interrupted()方法进行代替;

而suspend()方法我们可以用wait()方法进行代替;


守护线程

如果没有守护线程的话,进程必须要所有线程执行完之后才会结束,但是如果你把一个线程设置为守护线程的话,那么这个守护线程是可以没有结束但进程就能结束了的;

常见:比如垃圾回收器就是守护线程,把其他没有引用的对象回收,其他线程被回收,进程就结束了,如果你把整个程序终止,垃圾回收器也就gg了;

这里,t1被设置为守护线程,也就是说只需要主线程完成,进程就结束了

package com.example.juc.Test;

import lombok.extern.slf4j.Slf4j;

import static java.lang.Thread.sleep;

/**
 * @author diao 2022/4/1
 */
@Slf4j(topic = "c.daemonTest")
public class daemonTest {
    public static void main(String[] args) throws InterruptedException {
        test();
    }

    public static void test() throws InterruptedException {
        log.debug("开始运行...");
        Thread t1 = new Thread(() -> {
            log.debug("开始运行...");

            try {
                sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            log.debug("运行结束...");
        }, "daemon");

        //设置该线程为守护线程
        t1.setDaemon(true);
        
        sleep(1);
        log.debug("运行结束");
    }
}

线程状态: 

可运行状态:比如yield()就绪状态;

运行状态就是已经start(),线程开始运行了;

阻塞状态比如:sleep(),此时线程不会用到CPU,会导致线程上下文切换,完了之后,操作系统会将其唤醒——>进入可运行状态; 

 在Java中,Runnable既包含运行状态,又包含阻塞状态与可运行状态(就绪状态);

timed—Waitting状态

 blocked:

上锁拿不到资源;

waitting:

等待其他线程执行完,比如join()方法

例子:洗茶壶(多线程处理问题)

 

package com.example.juc.Test;

import lombok.extern.slf4j.Slf4j;

import static java.lang.Thread.sleep;

/**
 * @author diao 2022/4/1
 */
@Slf4j(topic = "c.WaterTest")
public class WaterTest {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            log.debug("洗水壶");
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("烧开水");
            try {
                sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "老王");

        Thread t2 = new Thread(() -> {
            log.debug("洗水壶");
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("洗茶杯");
            try {
                sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("拿茶叶");
            try {
                sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //因为t1线程执行时间>t2,所以进行等待,等待t1线程执行完再继续下一步操作
            try {
                t1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("小王泡茶");
        }, "小王");

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

}

 

 缺陷:一个线程不能拿到另一个线程的结果

这里我们用到了同步执行与异步执行——>异步体现在两个线程同时执行,也就是并行

同步的话体现在join,小王线程要等待第一个线程执行完后才会继续执行


小结:

start(): 启动新线程

run(): 线程中启动后会调用的方法,运行

sleep():线程阻塞

join():当两个线程中,有一个线程使用该方法,就会等待另一个线程执行完才会继续执行,(同步执行);

Interrupt:打断线程,如果线程是在阻塞状态的话,打断线程,线程状态为false,否则为true;

实际应用:

异步调用:主线程执行的时候,其他现场异步执行耗时操作;

提高效率:并行,实际开发中,并行并发其实都会存在的,毕竟线程数一般>>核数,所以说我们要合理规划线程数;

线程的三种创建方式:1.new Thread(),run方法重写在里面,

2.new一个Runnable,在里面写任务,实现任务与线程创建分离的效果,

3.通过Callable,能够传递线程结果,通过new 一个FutureTask的方式将Callable封装到里面,重写call()方法,然后将FutureTask引用封装到线程中即可;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fairy要carry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值