Java基础之多线程(二)4月打卡day09

举报
java厂长 发表于 2022/04/09 22:28:45 2022/04/09
【摘要】 Java基础之多线程(二)4月打卡day09关于作者作者介绍🍓 博客主页:作者主页🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。1、多线程要使用多线程必须有一个前提,有一个线程的执行主类。从多线程开始,Java正式进入到应...

Java基础之多线程(二)4月打卡day09

关于作者

  • 作者介绍


🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻。

1、多线程

要使用多线程必须有一个前提,有一个线程的执行主类。从多线程开始,Java正式进入到应用部分,而对于多线程的开发,从JavaEE上表现的并不是特别多,但是在Android开发之中使用较多,并且需要提醒的是,鄙视面试的过程之中,多线程所问道的问题是最多的。

1.6 线程的操作状态

image-20210816140312921

当我们多线程调用start方法之后不会立刻执行,而是进入就绪状态,等待进行调度后执行,需要将资源分配给你运行后,才可以执行多线程的代码run()中的代码当执行一段时间之后,你需要让出资源,让其他线程来执行,这个时候run()方法可能还没有执行完成,只执行了一半,那么我么我们就需要让资源,随后重新进入就绪状态,重新等待分配新资源继续执行。当线程执行完毕后才会进入终止状态。总结就一句话:线程执行需要分配资源,资源不能独占,执行一会让出资源给其他程序执行。

1.7 Callable实现多线程

jdk增加新的工具类java.util.concurrent

@FunctionalInterface
public interface Callable<V>

Runnable中的run()方法虽然也是线程的主方法,但是其没有返回值,因为它的设计遵循了我们主方法的设计原则:线程开始就别回头。但是在很多时候需要一些返回值,例如:当某些线程执行完成后可能带来一些返回结果,这种情况下我们就只能通过Callabale来实现多线程。

通过分析源代码可以找到一些关系

image-20210816142619937

Callable定义线程主方法启动并取得多线程执行的总结果

package com.day12.demo;
​
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
​
class MyTicket1 implements Callable<String>{    
    @Override
    public String call() throws Exception {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
            System.out.println("买票 ,x = " + i);
        }
        return "票卖完了,下次吧";
    }
}
public class CallableDemo {
    @SuppressWarnings({ "unused", "rawtypes", "unchecked" })
    public static void main(String[] args) throws Exception {
        FutureTask<String> task = new FutureTask<>(new MyTicket1());
        new Thread(task).start();
        System.out.println(task.get());
    }
}

这种形式主要就是返回我们的操作结果。

1.8 线程命名和取得

线程本身是属于不可见的运行状态的,即:每次操作的时候是无法预料的,所以如果要想在程序之中操作线程,唯一依靠的就是线程的名称,而要想取得和设置线程的名称可以使用以下的方法:

方法名称 类型 描述
public Thread(Runnable target,String name); 构造 声明参数
public final void setName(String name); 普通 设置线程名称
public final String getName() 普通 取得线程名称

但是由于线程的状态不确定,所以每次可以操作的线程都是正在执行run()方法的线程,那么取得当前线程对象的方法:public static Thread currentThread()。

线程名称的取得

package com.day12.demo;
​
class MyThread implements Runnable{
    public void run(){
        System.out.println(Thread.currentThread().getName());
            }
}
public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThread mt = new MyThread();
        new Thread(mt).start();//Thread-0
        new Thread(mt).start();//Thread-1
        new Thread(mt).start();//Thread-2
        new Thread(mt,"A").start();//A
        new Thread(mt,"B").start();//B
        new Thread(mt,"C").start();//C
    }
}
​

如果说现在为线程设置名字的话,那么会使用用户定义的名字,而如果没有设置线程名称,会自动分配一个名称这一点操作和之前讲解的static命名类似。

package com.day12.demo;
class MyThread2 implements Runnable{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println(Thread.currentThread().getName());
    }
    
}
public class RenameThreadDemo {
    public static void main(String[] args) {
        MyThread2 mt = new MyThread2();
        mt.run();//直接通过对象调用方法
        new Thread(mt).start();
    }
}

观察以上程序我们发现,线程的启动都是通过主线程创建并启动的,主方法就是一个线程。

进程在哪里?

实际上每当使用了java命令去解释程序的时候,都表示启动了一个新的JVM进程。而主方法只是这个进程上的一个线程而已。

1.9 线程的休眠

线程的休眠指的是让程序休息一会等时间到了在进行执行。方法:public static void sleep(long millis) throws InterruptedException,设置的休眠单位是毫秒。

package com.day12.demo;
class MyThread implements Runnable{
    public void run(){
        for(int x=0;x<100;x++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"x="+x);
        }
    }
}
public class Test {
    public static void main(String[] args) throws Exception{
        // TODO Auto-generated method stub
        MyThread mt = new MyThread();
        new Thread(mt,"线程A").start();
        new Thread(mt,"线程B").start();
    }
}
1.10 线程的优先级

从理论上讲,线程的优先级越高,越有可能先执行。如果要想操作线程的优先级有如下两个方法:

  • 设置线程优先级:public final void setPriority(int newPriority);

  • 取得线程优先级:public final int getPriority();

发现设置取得优先级的时候都是利用一个int型数据的操作,而这个int型数据有三种取值:

最高优先级:public static final int MAX_PRIORITY,10;

中等优先级:public static final int NORM_PRIORITY,5;

最低优先级:public static final int MIN_PRIORITY,1;

设置优先级

package com.day12.demo;
class MyThread3 implements Runnable{
​
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "i = "+ i);
        }
    }
    
}
public class PriorityDemo {
    public static void main(String[] args) {
        MyThread3 mt = new MyThread3();
        Thread thread1 = new Thread(mt,"线程A");
        Thread thread2 = new Thread(mt,"线程B");
        Thread thread3 = new Thread(mt,"线程C");
        thread1.setPriority(Thread.MIN_PRIORITY);
        thread2.setPriority(Thread.MAX_PRIORITY);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

主方法只是一个中等优先级。

# 后语

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。