首页 > 编程语言 >多线程(Java.Thread)学习

多线程(Java.Thread)学习

时间:2024-01-13 23:44:27浏览次数:31  
标签:love Java Thread int void 线程 new 多线程 public

多线程(Java.Thread)学习

线程简介:

1、线程是独立执行的路径
2、程序运行时有很多后台进程 比如主线程、young.gc、full.gc()
3、main是主线程,系统入口,用于执行整个程序
4、一个进程中、如果开辟多个线程,线程的运行由调度器安排调度、调度器的先后顺序不能人为干预
5、对同一份资源操作时,会存在资源抢夺问题,需要加入并发控制
6、线程会带来额外的开销,比如cpu调度时间,并发控制开销
7、每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

线程实现:

Thread

/**
 * @Description:TODO
 * @Author:Administrator
 * @Create 2024/1/12
 */
public class ThreadTest extends Thread{
    // 线程入口点
    @Override
    public void run() {
        // 线程体
        for (int i = 0;i<10;i++){
            System.out.println("我在看蒂法....."+i);
        }
    }
    public static void main(String[] args) {
        ThreadTest threadTest = new ThreadTest();
            threadTest.start();//开启线程,不一定立即执行 需要cpu调度
            threadTest.run();//立即执行线程 
        for (int i =0;i<10;i++){
            System.out.println("我在学Java Thread"+i);
        }
    }
}

开启 Thread 线程 下载网图,验证start方法线程执行交给cpu。

public class ThreadTest2 extends Thread {
    private String url;
    private String name;

    public ThreadTest2(String url,String name){
        this.url = url;
        this.name =name;
    }
    @Override
    public void run() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.download(url,name);
        System.out.println("下载了文件名为:"+name);
    }
    public static void main(String[] args) {
        ThreadTest2 threadTest1 = new ThreadTest2("https://aistyle.art/assets/files/2023-06-30/1688166112-995353-348703237-145251275241612-1956428239713994473-n.jpg","明日香1.jpg");
        ThreadTest2 threadTest2 = new ThreadTest2("https://bkimg.cdn.bcebos.com/pic/8b13632762d0f703918fecd9c0b1463d269759ee6f28?x-bce-process=image/format,f_auto/resize,m_lfit,limit_1,h_300","明日香2.jpg");
        ThreadTest2 threadTest3 = new ThreadTest2("https://aistyle.art/assets/files/2023-06-30/1688166112-995353-348703237-145251275241612-1956428239713994473-n.jpg","明日香3.jpg");

        threadTest1.start();
        threadTest2.start();
        threadTest3.start();
    }
}
class WebDownloader{
    //
    public void download(String url,String name){
        try{
            FileUtils.copyURLToFile(new URL(url),new File(name));
            System.out.println("下载完成");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

实现runable接口

public class TestThread3 implements Runnable {
    public static void main(String[] args) {
        TestThread3 testThread3 = new TestThread3();
        new Thread(testThread3).run();

        for (int i = 0; i < 10; i++) {
            System.out.println("我在学习" + i);
        }
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("我在聊天" + i);
        }
    }
}

初识并发问题

package org.example.redisson.JavaThread;

/**
 * @Description:TODO
 * @Author:Administrator
 * @Create 2024/1/12
 */

/**
 * 创建线程方式2:实现runable 接口重写run
 * 执行线程需要啊丢入new Thread(TestThread3)
 * 官方推荐 实现runable接口的方式
 */
public class TestThread4 implements Runnable {

    // 模拟票数
    private int ticketNums = 100;
    @Override
    public void run() {
        while (true){
            // 票剩余0时退出
            if (ticketNums <= 0){
                break;
            }
            // 模拟延时
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 对票数加锁
            synchronized ((Object)ticketNums){
                // 再次判断
                if (ticketNums <= 0){
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
            }
        }
    }

    public static void main(String[] args) {
        TestThread4 ticket = new TestThread4();

        new Thread(ticket,"陈X华").start();
        new Thread(ticket,"席X辉").start();
        new Thread(ticket,"李X杰").start();
    }
}

龟兔赛跑

public class TestThread5 implements Runnable{
    private static String Winer;
    // 比赛内容
    public void run(){
        // 如果线程是兔子 让他休息20ms
        if(Thread.currentThread().getName().equals("兔子")){
            try{
                Thread.sleep(20);
            }catch(RuntimeException | InterruptedException e){
                e.printStackTrace();
            }
        }
        for(int i = 1;i<= 10;i++){
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
            // 判断比赛是否结束
            Boolean flage = gameOver(i);
            if (flage){
                break;
            }
        }
    }

    public static void main(String[] args){
        TestThread5 testThread5 = new TestThread5();
        new Thread(testThread5,"兔子").start();
        new Thread(testThread5,"乌龟").start();
    }
    public Boolean gameOver(int step){
        // 胜利者诞生 停止比赛
        if(Winer != null){
            return true;
        }
        // 跑过了10 步 停止比赛
        if(step == 10){
            Winer = Thread.currentThread().getName();
            System.out.println("胜利者是"+Winer);
            return true;
        }
        return false;
    }
}

callable

函数式接口 lambda

JDK8 之前的写法


 public class TestLambda2{
// 一个接口只有一个实现方法:叫做函数式接口
interface ILove{
        void love(int a);
    }

public static void main(String[] args){
       ILove i = new I();
       i.love(521);
    }

 class I implements ILove{
        @Override
    public void love(int a){
            System.out.println("i love you " + a);
        }
    }
 } 

简化1:使用静态内部类

# 使用静态内部类

public class TestLambda2{
// 一个接口只有一个实现方法:叫做函数式接口
interface ILove{
        void love(int a);
    }

public static void main(String[] args){
       ILove i = new I();
       i.love(521);

    }
static class I implements ILove{
        @Override
    public void love(int a){
            System.out.println("i love you " + a);
        }
    }
 } 

简化2:局部内部类

public class TestLambda2{
// 一个接口只有一个实现方法:叫做函数式接口
interface ILove{
        void love(int a);
    }

public static void main(String[] args){
    class I implements ILove{
    @Override
    public void love(int a){
            System.out.println("i love you " + a);
        }
    }
       ILove i = new I();
       i.love(521);

    }
 } 

简化3:匿名内部类(通过new 构建 没有方法名)

interface ILove{
        void love(int a);
    }

public class TestLambda2{
// 一个接口只有一个实现方法:叫做函数式接口

public static void main(String[] args){
    ILove  i = new ILove(){
        @Override
        public void love(int a){
            System.out.print("i love you " + a)
        }
    };
        i.love(521);
    }
 } 

最终lambda版本

interface ILove {
    void love(int a,int b);
}
public class TestLambda2 {
    // 一个接口只有一个实现方法:叫做函数式接口
    public static void main(String[] args) {
        ILove i = (a,b) -> {
                System.out.println("i love you " + a+b);
        };
        i.love(520,521);
    }
}
Lambda总结

1、接口中只能有一个方法;
2、lambda执行业务逻辑时 必须带{},除非业务逻辑只有一行
3、多个参数 也可以去掉参数类型(全部去掉)

线程状态:

创建 new Thread()

就绪(等待cpu调度) start();

阻塞(阻塞结束后 等待cpu调度) sleep()、wait()或同步锁

sleep
sleep(ms) 指定当前线程阻塞的毫秒数;
sleep 存在异常InterruptedException;
sleep 时间到达后线程进入就绪状态;
sleep 可以模拟网络延时。倒计时等
每一个对象都有一把锁。sleep不会释放锁;
/**
 * @Description: 联系sleep 倒计时
 * @Author:Administrator
 * @Create 2024/1/13
 */

public class TestThreadSleep{
    public static void main(String[] args) throws InterruptedException {
        tenShutDown();
    }

    static void tenShutDown() throws InterruptedException {
        int num = 10;
        while (true){
            Thread.sleep(1000);
            System.out.println( num-- );
            if (num <= 0){
                break;
            }
        }

    }
}

join 使线程阻塞,相等于vip先执行
/**
 * @Description:测试 join,会使线程阻塞
 * @Author:Administrator
 * @Create 2024/1/13
 */

public class TestThreadJoin implements Runnable{

    @Override
    public void run() {
        for (int i = 1; i < 101; i++) {
            System.out.println("vip来了 统统闪开~ !"+i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        TestThreadJoin testThreadJoin = new TestThreadJoin();
        Thread thread = new Thread(testThreadJoin);
        thread.start();
        
        for (int i = 1; i < 101; i++) {
            System.out.println("main"+ i);
            if(i == 10){
                thread.join();// 强制执行 run方法 线程
            }
        }
    }
}

运行

start()、run()

销毁

不建议用stop、die废弃或官方不推荐的方法
  • 推荐基数的方式 停止线程
/*
 * @Description:不建议用stop、die废弃或官方不推荐的方法
 * 推荐基数的方式 停止线程
 * @Author:Administrator
 * @Create 2024/1/13
 */
public class TestThreadStop implements Runnable {
    public Boolean flag = true;
    @Override
    public void run() {
        int i = 0;
        while (flag) {
            System.out.println("走了" + i++ + "步数");
        }
    }

    // 设置一个公开的停止方法
    public void stop() {
        this.flag = false;
    }

    public static void main(String[] args) {
        TestThreadStop testThreadStop = new TestThreadStop();

        new Thread(testThreadStop).start();

        for (int i = 0; i < 100; i++) {
            System.out.println("main"+ i);
            if (i == 90) {
                // 循环90次的时候 停止线程
                testThreadStop.stop();
                System.out.println("线程该停止了");
            }
        }
    }

}

线程同步

线程通信

高级主题

JDK15 Lock

标签:love,Java,Thread,int,void,线程,new,多线程,public
From: https://www.cnblogs.com/czh4869/p/17963221

相关文章

  • C++多线程并发(一)--- 线程创建与管理
    目录进程和线程的区别何为并发?C++11线程基本操作C++11新标准多线程支持库std::thread类成员函数std::thread的关键总结C++中多线程创建C++的多线程可以充分利用计算机资源,提高代码运行效率。在这里总结了一些多线程应用过程中的基本概念和用法。进程和线程的区别进程是一......
  • 深入探索JVM:理解Java程序在虚拟机中的存储和管理
    大家好,我是大圣,很高兴又和大家见面。今天给大家带来图解JVM系列的第四篇文章,我们写的Java程序是怎么在JVM里面存储的。本次大纲如下:前面知识回顾上一篇图解JVM系列:揭秘运行时数据区的设计与实现文章说了JVM运行时数据区的设计理念,我们是通过冯·诺依曼结构来类比引......
  • 用jacoco统计JAVA项目测试代码覆盖率
    一、概述Jacoco统计的是全量代码覆盖率。它不仅支持生成单元测试的覆盖率,也支持监控生成接口测试,功能测试的覆盖率。在新一代精准测试技术流的影响中,各大型单位对覆盖率的追求越来越迫切。作为一款开源产品,它主机面向Java语言,能够在字节码层面给出覆盖率,同时也能将字节码关联到......
  • NUS CS1101S:SICP JavaScript 描述:四、元语言抽象
    原文:4MetalinguisticAbstraction译者:飞龙协议:CCBY-NC-SA4.0...魔法就在于文字——Abracadabra,开门,以及其他——但一个故事中的魔法词在另一个故事中并不神奇。真正的魔法是理解哪些词起作用,何时起作用,以及为什么起作用;诀窍就是学会这个诀窍。...而这些词是由我们字母表......
  • NUS CS1101S:SICP JavaScript 描述:五、使用寄存器机进行计算
    原文:5ComputingwithRegisterMachines译者:飞龙协议:CCBY-NC-SA4.0我的目标是表明天堂机器不是一种神圣的生命体,而是一种钟表(相信钟表有灵魂属性的人将制造者的荣耀归功于作品),因为几乎所有多种运动都是由一种最简单和物质力量引起的,就像钟表的所有运动都是由单一重力引起......
  • NUS CS1101S:SICP JavaScript 描述:前言、序言和致谢
    前言原文:Foreword译者:飞龙协议:CCBY-NC-SA4.0我有幸在我还是学生的时候见到了了不起的AlanPerlis,并和他交谈了几次。他和我共同深爱和尊重两种非常不同的编程语言:Lisp和APL。跟随他的脚步是一项艰巨的任务,尽管他开辟了一条优秀的道路。尽管如此,我想重新审视他在这本书......
  • NUS CS1101S:SICP JavaScript 描述:三、模块化、对象和状态
    原文:3Modularity,Objects,andState译者:飞龙协议:CCBY-NC-SA4.0变化中安宁(即使它在变化,它仍然保持不变。)——赫拉克利特变化越大,越是相同。——阿方斯·卡尔前面的章节介绍了构成程序的基本元素。我们看到了原始函数和原始数据是如何组合成复合实体的,我们也了解......
  • Java Web中文乱码的问题
    本编文章列举了JavaWeb编程中所有可能导致中文乱码的问题以及解决方法1、html页面乱码首先第一点便是html页面乱码问题例如:此时我们需要在项目中找到该网页的html文件,在html文件头部中找到metacharset="";然后将meta中的charset改为charset="UTF-8"如下图示:2、request乱码在debug......
  • Java使用modbus4j通过串口modbus-rtu协议 连接设备 demo
    前言项目中需要使用串口来连接操控烟雾报警器且只能使用modbus-rtu协议在找了一堆资料后终于成功了在此呈上代码和资料链接【ModBus】modbus之modbus4j的使用和流程原理解析(5)-CSDN博客使用modbus4j通过串口解析modbus协议(java)_javamodbus4j-CSDN博客 串口通讯需要使用modbus4j......
  • 《Java编程思想第四版》学习笔记54--关于UncaughtExceptionHandler
    Java中在处理异常的时候,通常的做法是使用try-catch-finally来包含代码块,但是Java自身还有一种方式可以处理——使用UncaughtExceptionHandler。它能检测出某个线程由于未捕获的异常而终结的情况。当一个线程由于未捕获异常而退出时,JVM会把这个事件报告给应用程序提供的UncaughtExce......