首页 > 其他分享 >多线程笔记

多线程笔记

时间:2024-01-21 23:45:40浏览次数:27  
标签:void 笔记 线程 println new 多线程 public out

线程创建

3

继承Thread类

//线程创建方式1:继承thread1,重写run方法,调用start开启线程
public class Thread1 extends Thread {
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码"+i);
        }
    }

    public static void main(String[] args) {

        //创建线程对象,调用start方法
        Thread1 thread1 = new Thread1();
        thread1.start();

        //主线程
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习"+i);
        }
    }
}

/**
 * 多线程并发网络下载器
 * WebDownloader实现了网络图片下载功能;downloader方法输入为目标链接地址、下载图片文件名;结果为保存对应文件到本地
 * Thread2类中的run方法调用downloader方法;并且通过start实现多线程并发下载图片
 * 结果显而易见 执行具有无序性
 */
//多线程同步下载图片
public class Thread2 extends Thread {
    private String url;
    private String name;

    public Thread2(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url, name);
        System.out.println("文件名" + name);
    }

    public static void main(String[] args) {
        Thread2 thread21 = new Thread2("/i/ll/?i=2711126564c842689248e53bbf4d85e8.png", "t1.png");
        Thread2 thread22 = new Thread2("/i/ll/?i=4b97a32c6d9f4caa8617099065d02e3c.png", "t2.png");
        Thread2 thread23 = new Thread2("/i/ll/?i=419537bd2d5e4fdfaa70fb8b8ed17663.png", "t3.png");
        thread21.start();
        thread22.start();
        thread23.start();
    }
}

//下载器
class WebDownloader{
    //下载方法
    public void downloader(String url,String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("io异常,downloader方法出现问题");
        }
    }
}

实现Runnable接口

//线程创建方式2:重写Runnable,重写run方法,执行线程丢入runnable接口实现类,调用start开启线程
public class Thread3 implements Runnable{
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码"+i);
        }
    }

    public static void main(String[] args) {
        Thread3 thread3 = new Thread3();

        //创建线程对象,调用start方法(区分于继承Thread,将new的对象当参数new一个Thread)
        new Thread(thread3).start();

        //主线程
        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习"+i);
        }
    }
}

实现Callable接口

对比

对比

高并发问题

买火车票

package thread;
//高并发模拟之买火车票
public class GetTicket implements Runnable{
    private int ticket = 10;

    @Override
    public void run() {
        while(true){
            if(ticket<=0) break;
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticket--+"张票");
        }
    }

    public static void main(String[] args) {
        GetTicket t1 = new GetTicket();

        new Thread(t1,"xiaoming").start();
        new Thread(t1,"xiaohong").start();
        new Thread(t1,"xiaogang").start();
        //结果:除了结果不可预测,还有多个线程共用一张票的情况
    }
}

龟兔赛跑

public class Race implements Runnable {
    private static String winner;

    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            if(Thread.currentThread().getName().equals("兔子") && i%50==0) {//兔子到50开始睡觉
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            if(isGameOver(i)) break;
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }

    private boolean isGameOver(int step){
        if(step == 100){
            winner = Thread.currentThread().getName();
            System.out.println("winner is "+winner);
        }
        return winner != null || step >= 100;
    }

    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟111").start();

    }
}

静态代理_Runnable原理

/**
 * 静态代理:
 * 设计一个接口,
 * 真实对象和代理对象都要实现这个接口,
 * 代理对象代理真实对象,
 * 真实对象专注做自己的事,
 * 代理对象代做真实对象做不到的事,
 * 这就是Runnable的原理-> new Thread(myThread).start();
 */
public class StaticProxy {
    public static void main(String[] args) {
        /*You you = new You();
        WeddingCompany weddingCompany = new WeddingCompany(you);
        weddingCompany.marry();*/
        //这么写和多线程实现Runnable一样
        new WeddingCompany(new You()).marry();
    }


}

interface Marry{
    void marry();
}

//真实角色,我去结婚
class You implements Marry{
    @Override
    public void marry() {
        System.out.println("我结婚了");
    }
}
//代理角色,婚庆公司帮我做before和after
class WeddingCompany implements Marry{
    private Marry target;

    public WeddingCompany(Marry target) {
        this.target = target;
    }



    @Override
    public void marry() {
        before();
        this.target.marry();
        after();
    }

    void before(){
        System.out.println("收钱");
    }

    void after(){
        System.out.println("打扫");
    }
}

Lambda表达式

lamda

lambda函数式接口

/**
 * 推导了lambda表达式简化函数式编程的过程
 * 如果一个接口只有一个函数,实例化它相当于调用这个函数
 * 用lambda表达式可以极大简化调用过程
 */
public class TestLamda {

    //3.静态内部类
    static  class Like2 implements ILike{
        @Override
        public void lambda() {
            System.out.println("i like lambda2");
        }
    }


    public static void main(String[] args) {
        Like like = new Like();
        like.lambda();

        Like2 like2 = new Like2();
        like2.lambda();

        //4.局部内部类
        class Like3 implements ILike{
            @Override
            public void lambda() {
                System.out.println("i like lambda3");
            }
        }

        Like3 like3 = new Like3();
        like3.lambda();

        //5.匿名内部类
        like = new Like() {
            @Override
            public void lambda() {
                System.out.println("i like lambda4");
            }
        };
        like.lambda();

        //6.lambda简化
        ILike like4 = ()-> {
            System.out.println("i like lambda5");
        };
        like4.lambda();



    }


}

//1.函数接口
interface ILike{
    void lambda();
}

//2.实现类
class Like implements ILike{
    @Override
    public void lambda() {
        System.out.println("i like lambda");
    }
}
//lambda表达式简化
public class Testlam {

    public static void main(String[] args) {
        int n = 5;
        //简化:可以不带参数类型;一个参数可以不带();void方法且只有一行可以不带{}
        Test1 myT = n1-> {return n1*n1;};
        Test2 myT2 = n1-> System.out.println(n1*n1);
        int re = myT.reSequre(n);
        System.out.println(re);
        myT2.reSequre(n);
    }

}

interface Test1{
    int reSequre(int n);
}
interface Test2{
    void reSequre(int n);
}

线程状态和实现

五个状态

停止线程stop

线程停止

package state;

/**
 * 线程停止方法:设定标志位,调用stop()方法使标志位变为0,进而停止线程
 */
public class TestStop implements Runnable {
    boolean flag = true;//标志位

    @Override
    public void run() {
        int i = 0;
        while (flag){//停止控制
            System.out.println("run thread"+i++);
        }

    }
    //停止线程
    public void stop(){
        this.flag = false;
    }


    public static void main(String[] args) {
        TestStop testStop = new TestStop();
        new Thread(testStop).start();//线程
        
        //主线程
        for (int i = 0; i < 1000; i++) {
            System.out.println("main"+i);
            if(i==900){
                testStop.stop();
                System.out.println("停止 i="+i);
            }
        }
    }
}

线程休眠sleep(进入阻塞)

sleep

//sleep模拟时钟
public class TimeClock {
    public static void main(String[] args) {
        Clock clock = new Clock(10);
        new Thread(clock).start();

    }
}

class Clock implements Runnable{
    @Override
    public void run() {
        this.clock();
    }

    private int clk;

    public Clock(int clk) {
        this.clk = clk;
    }

    void clock(){
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("time:"+this.clk--);
            if(clk<0){
                System.out.println("time out");
                break;
            }
        }


    }
}

线程礼让yield(进入就绪)

yield

yield代码

执行结果:可能礼让成功,abab;可能礼让失败,aabb

本质是让进程由执行变为就绪,竞争下一次的执行机会;取决于调度算法

线程强制执行join

join

join代码

执行结果:main中 i==200时 执行thread中的语句直到结束,并且其他线程阻塞

观测线程状态Thread.State

state

state1

state2

结果:

NEW——RUNNABLE——若干个TIMED-WAITIN——TERMINATED

新建 运行/就绪 睡眠(阻塞) 终止

线程优先级

优先级

优先级1

优先级2

优先级3

优先级4

守护daemon线程

守护线程

/**
 * 守护线程,可以不用确保其运行完毕
 * 运行结果:manba out之后,god像蛆一样再运行了几句,然后痛苦的似了

标签:void,笔记,线程,println,new,多线程,public,out
From: https://www.cnblogs.com/autismer-ustcsse/p/17978717

相关文章

  • Neo4j图形存储学习笔记
    一、Neo4j图数据库:图形数据库(GraphDatabase)是NoSQL数据库家族中特殊的存在,用于存储丰富的关系数据。与传统的关系型数据库相比,图形数据库更适合处理具有复杂关系和网络结构的数据。Neo4j是目前最流行的图形数据库之一,它支持完整的事务处理,并采用节点与关系的方式来组织和表示数......
  • PHP学习第八天:扩展开发与多线程编程
    在PHP学习的第八天,我深入了解了扩展开发和多线程编程的概念。早上,我学习了如何编写PHP扩展。扩展是PHP的模块,可以提供额外的功能。我了解了扩展开发的基础知识,如C语言和PHPAPI。通过编写一个简单的扩展,我熟悉了扩展的结构和编写过程。了解扩展开发使我能够更深入地了解PHP的内部工......
  • Infix to postfix conversion using stack【1月21日学习笔记】
    点击查看代码//Infixtopostfixconversionusingstack#include<iostream>#include<stack>//stackfromstandardtemplatelibrary(STL)#include<string>usingnamespacestd;stringInfixToPostfix(stringexp);boolHasHigherPrecedence(charopr1,......
  • 并发编程之多线程理论篇
    什么叫线程线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程自己不用有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个一个进程的其他线程共享其所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个......
  • 并发编程之多线程操作篇
    多线程简单介绍多线程,或者说多任务,指的是操作系统同时运行多个任务。例如,听歌、洗衣服、看视频可以同时进行,这种就是多任务。单核CPU执行多任务:操作系统轮流让各个任务交替执行,任务1执行t1时间,切换到任务2,任务2执行t2时间,再切换到任务3,执行t3时间...如此反复执行,表面上看,每个任......
  • 光平面标定笔记
    由于......
  • 水浒传笔记
    水浒传笔记作者:施耐庵文体:我国第一部歌颂农民起义的章回体小说主要内容:《水浒传》描述了北宋末年以宋江为首的广大农民在贪官逼迫下,无以为生,纷纷占山为王,结盟起义的历史史实,记述了起义发生、发展到失败的全过程人物鲁达别称:鲁智深鲁提辖花和尚事件:拳打镇关西......
  • <学习笔记> 杜教筛
    杜教筛处理数论函数的前缀和问题,可以在低于线性的复杂度里求出\(S(n)=\sum_{i=1}^{n}f(i)\)。对于任意一个数论函数\(g\),必须满足:\[\sum_{i=1}^{n}(f*g)(i)=\sum_{i=1}^{n}\sum_{d\midi}g(d)*d(\frac{i}{d})\]\[=\sum_{d=1}^{n}g(d)\sum_{j=1}^{\lfloor\frac{n}{d}......
  • C++ ——vector数组笔记
     vector是C++标准库中的一个动态数组容器(SequenceContainer),它可以自动管理内存大小,可以在运行时根据需要动态增长或缩小。它是一个非常常用且强大的容器,用于存储一系列元素。可以简单的认为,vector是一个能够放任意类型的动态数组。下面详细介绍 vector 的使用方法......
  • Shiro学习笔记
    Shiroshiro外部来看:内部来看:认证登录基本流程:收集用户身份/凭证,如用户名密码调用Subject.login(),进行登录,如果错误返回异常创建自定义的Realm类,继承org.apache.shiro.realm.AuthorizingRealm类,实现doGetAuthenticationInfo()方法授权流程:首先调用Subject.isPermit......