• java多线程


    多线程实现方式

    继承Thread类

    流程

    1.定义一个类继承Thread,

    2.重写run方法

    3.创建对象,调用start方法;开启线程

    代码
    1. 继承Thread类,重写run方法
    2. public class MyThread extends Thread{
    3. public static void main(String[] args) {
    4. }
    5. @Override
    6. public void run() {
    7. for (int i = 0; i < 10; i++) {
    8. System.out.println(getName()+"hello,world");
    9. }
    10. }
    11. }
    12. 创建线程,调用start对象创建线程
    13. public class Main {
    14. public static void main(String[] args) {
    15. MyThread t1=new MyThread();
    16. MyThread t2=new MyThread();
    17. MyThread t3=new MyThread();
    18. t1.setName("线程一");
    19. t2.setName("线程二");
    20. t3.setName("线程三");
    21. t1.start();;
    22. t3.start();
    23. t2.start();
    24. }
    25. }

     实现Runnable接口

    流程

    1.实现Runnable接口

    2.重写run方法

    3.创建自己的类

    4.创建Thread类,传递自己的类;

    5.启动run方法

    代码
    1. public class MyThread1 implements Runnable{
    2. @Override
    3. public void run() {
    4. for (int i = 0; i <10 ; i++) {
    5. Thread t=Thread.currentThread();
    6. System.out.println(t.getName()+"mike");
    7. }
    8. }
    9. }
    10. Thread t7=new Thread(t6);
    11. Thread t5=new Thread(t4);
    12. t5.setName("线程5");
    13. t7.setName("线程7");
    14. t5.start();
    15. t7.start();

    利用Callable接口和Future接口实现

    Callable和FutureTask可以返回线程的结果,并对线程进行管理;

    Callable可以返回结果,FutureTask可以对线程进行管理,

    流程

    流程:创建Callable对象->Callable对象作为FutureTask对象的构造参数,创造FutureTask对象,->将FutureTask对象作为参数创建Thread对象->Thread对象调用start启动线程->FutureTask对象调用get方法返回线程的结果值;

    代码
    1. public class MyCallable implements Callable {
    2. public static void main(String[] args) throws ExecutionException, InterruptedException {
    3. //可以返回现成的结果;
    4. MyCallable ms=new MyCallable();
    5. //利用futuretask管理线程;
    6. FutureTaskft=new FutureTask<>(ms);
    7. Thread t=new Thread(ft);
    8. t.start();
    9. Integer res=ft.get();
    10. System.out.println(res);
    11. }
    12. @Override
    13. public Integer call() throws Exception {
    14. int sum=0;
    15. for (int i = 0; i < 10; i++) {
    16. sum+=i;
    17. }
    18. return sum;
    19. }//表示返回结果的类型
    20. }

    三种方式的不同

    前两种无法返回线程的结果,第三种可以,推荐第三种。

    Thread类的方法

    常见成员方法

    sleep方法:将会让当前线程休眠,在main方法里就是main线程

    Thread.currentThread:获取当前线程的对象;

    1. public static void main(String[] args) throws InterruptedException {
    2. //将获取当前线程对象;
    3. Thread t=Thread.currentThread();
    4. Thread.sleep(5000);
    5. System.out.println(t.getName());
    6. }

    setpriority(int newpriority)

    设置当前线程的优先级,默认为5,最高10,最低1

    int getpriority()

    返回当前线程的优先级

    void setDaemon(boolean on);设置守护线程

    守护线程的生命周期与非守护线程 一样,非守护线程结束,守护线程也会结束;

    yield()

    当前线程将会让出CPU的执行权,但下一次仍然会抢夺;

    join()

    将线程插入到当前线程之前,只有线程执行完后,当前线程才会执行;

    1. public class MyThread5 extends Thread{
    2. public MyThread5() {
    3. }
    4. public MyThread5(String name) {
    5. super(name);
    6. }
    7. public static void main(String[] args) throws InterruptedException {
    8. MyThread5 t=new MyThread5("女神");
    9. // t.setPriority(9);
    10. MyThread3 t1=new MyThread3("备胎");
    11. // t1.setPriority(6);
    12. t1.setDaemon(true);
    13. t1.start();
    14. t.start();
    15. t.join();
    16. int i= Thread.currentThread().getPriority();
    17. System.out.println(i);
    18. for (int j = 0; j <11 ; j++) {
    19. System.out.println(j);
    20. }
    21. }
    22. @Override
    23. public void run() {
    24. for (int i = 0; i <10 ; i++) {
    25. System.out.println(getName()+" is "+i);
    26. Thread.yield();
    27. }
    28. }
    29. }

    线程的状态

    synchronized是一个bool量,表示两种状态,一个线程获得锁后,量的值改变,其余线程都无法获得。

    LOCK锁

    等待唤醒机制

     锁对象作为消息载体来管理线程,如唤醒,睡眠不同的线程,不同的线程使用相同的锁对象来传递消息。

    下图中使用 desk.lock作为锁,通过desk.lock调用wait,notifyAll方法,来唤醒与lock相关的线程,注意,多个线程应该绑定一把锁,所以lock采用静态对象,来传递消息;

    1. public class desk {
    2. public static int floodflag=0;
    3. public static int count=10;
    4. public static Object lock=new Object();
    5. }
    1. public class Foodie extends Thread{
    2. public Foodie(String name) {
    3. super(name);
    4. }
    5. @Override
    6. public void run() {
    7. while(true){
    8. synchronized (desk.lock){
    9. if(desk.count==0){
    10. break;
    11. }
    12. else{
    13. //判断资源
    14. //唤醒;
    15. //
    16. if(desk.floodflag==0){
    17. try {
    18. //休眠与唤醒
    19. //当前线程休眠
    20. desk.lock.wait();
    21. //唤醒与lock相关的线程
    22. desk.lock.notifyAll();
    23. } catch (InterruptedException e) {
    24. throw new RuntimeException(e);
    25. }
    26. }else{
    27. desk.count--;
    28. System.out.println("还能吃"+desk.count+"碗!");
    29. //唤醒lock相关的线程
    30. desk.lock.notifyAll();
    31. desk.floodflag=0;
    32. }
    33. }
    34. }
    35. }
    36. }
    1. public class Cook extends Thread{
    2. public Cook(String name) {
    3. super(name);
    4. }
    5. public static void main(String[] args) {
    6. Cook c=new Cook("吃货");
    7. Foodie f=new Foodie("厨师");
    8. c.start();
    9. f.start();
    10. }
    11. @Override
    12. public void run() {
    13. while (true){
    14. synchronized (desk.lock){
    15. if(desk.count==0){
    16. break;
    17. }
    18. else{
    19. if(desk.floodflag==1){
    20. //用锁对象调用wait;使用锁对象绑定
    21. try {
    22. desk.lock.wait();
    23. } catch (InterruptedException e) {
    24. throw new RuntimeException(e);
    25. }
    26. }
    27. else{
    28. System.out.println("厨师做了一碗面条");
    29. desk.floodflag=1;
    30. //唤醒吃货开吃
    31. desk.lock.notifyAll();
    32. }
    33. }
    34. }
    35. }
    36. }

     阻塞队列

    阻塞队列有ArrayBlockingQueue和LinkedBlockingQueue两种实现方式,前者用数组实现,后者用链表实现;

    注意生产者消费者使用同一个阻塞队列,分别使用take,put方法拿走,放入数据;

    线程的六种状态

    线程的状态转换采用以下函数获得:

     

    线程池

     

     

    自定义线程池

    ,参数

     线程池多大合适

     

  • 相关阅读:
    axios详解
    使用位运算技巧比较两个数中较大的数
    为什么说制造企业需要部署MES管理系统
    《痞子衡嵌入式半月刊》 第 53 期
    Codeforces Round #831 (Div. 1 + Div. 2)——A、B、C、D、E
    安卓Compose(一)
    新疆旅游创新产品迎活力 伊吾胡杨文旅品牌发布
    高等教育心理学:学生的认知发展
    Allegro在测量时如何同时显示双单位
    vscode的快捷键
  • 原文地址:https://blog.csdn.net/qq_41790844/article/details/133375716