多线程

多线程

本章核心概念

线程就是独立的执行路径;

在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;

main()称之为主线程,为系统的入口,用于执行整个程序;

在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能认为的干预的。

对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;线程会带来额外的开销,如cpu调度时间,并发控制开销。

每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

线程创建

创建线程方式一:Extends Thread

继承Thread类,重写run()方法,调用start开启线程

线程开启不一定立即执行 由cpu调度

public class Thread13_2 extends Thread{
    @Override
    public void run() {
        //run 方法线程体
        for (int i = 0; i <200 ; i++) {
            System.out.println("我在看代码"+i);

        }
    }
    public static void main(String[] args) {
        //创建线程对象
        Thread13_2 thread13_2 = new Thread13_2();
        //调用start()开启多线程
        thread13_2.start();

        for (int i = 0; i <2000 ; i++) {
            System.out.println("我在学习多线程"+i);

        }
    }
}

多线程下载图片

package demo13;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * @ClassName CommonsIo13_3
 * Description T0D0
 * @Author WangYuanpeng
 * Date 2021/4/1 16:39
 * Version 1.0
 **/
//实现多线程
public class CommonsIo13_3  extends Thread{

    private String url;//网络地址
    private String name;//文件名


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

    //下载图片线程执行体
    @Override
    public void run() {
        Downloader downloader = new Downloader();
        try {
            downloader.downloader(url,name);
            System.out.println("下载名"+name);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public static void main(String[] args) {
        CommonsIo13_3 t1 = new CommonsIo13_3("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=419416486,1672361391&fm=11&gp=0.jpg","1.jpg");
        CommonsIo13_3 t2 = new CommonsIo13_3("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fattach.bbs.miui.com%2Fforum%2F201205%2F03%2F01400598djmyeczcskh2yr.jpg&refer=http%3A%2F%2Fattach.bbs.miui.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1619859396&t=a8261d33aff9a7b4f28540351692d71c","2.jpg");
        CommonsIo13_3 t3 = new CommonsIo13_3("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fattach.bbs.miui.com%2Fforum%2F201304%2F25%2F195133e7a1l7b4f5117y4y.jpg&refer=http%3A%2F%2Fattach.bbs.miui.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1619859396&t=34e21c81c95e3621caa32627a1187317","3.jpg");

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

    //下载器
    class Downloader {

        public void downloader(String url,String name) throws IOException {


            try {
                FileUtils.copyURLToFile(new URL(url) ,new File(name));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("io异常,downloader");
            }

        }
    }
}

创建线程方式二 implements Runnable

实现Runnable

学习提示:查看JDK帮助文档

定义MyRunnable类实现Runnable接口
实现run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程

package demo13;

/**
 * @ClassName Runnable13_4
 * Description T0D0
 * @Author WangYuanpeng
 * Date 2021/4/1 17:07
 * Version 1.0
 **/

public class Runnable13_4 implements Runnable {
    @Override
    public void run() {
        //run 方法线程体
        for (int i = 0; i <2000 ; i++) {
            System.out.println("我在看代码"+i);

        }
    }
    public static void main(String[] args) {
        //创建线程对象
        Runnable13_4 runnable13_4 = new Runnable13_4();

        Thread thread = new Thread(runnable13_4);
        thread.start();
        //


        for (int i = 0; i <2000 ; i++) {
            System.out.println("我在学习多线程"+i);

        }
    }
}

Thread Runnable 小结

小结
◆继承Thread类
子类继承Thread类具备多线程能力

​ ◆启动线程:子类对象.start()

​ 不建议使用:避免OOP单继承局限性

◆实现Runnable接口

​ ◆实现接口Runnable具有多线程能力
​ ◆启动线程:传入目标对象+Thread对象.start()
​ ◆推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用

并发问题

多个线程操作同一个资源,线程不安全,数据紊乱

package demo13;

/**
 * @ClassName Runnable13_6
 * Description T0D0
 * @Author WangYuanpeng
 * Date 2021/4/2 15:59
 * Version 1.0
 **/
//多个线程操作同一个资源,线程不安全,数据紊乱
public class Runnable13_6 implements Runnable{

    private  int ticketNums = 10;
    @Override

    public void run() {
        while (true){

            if (ticketNums <= 0){
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums-- +"票");
        }
    }

    public static void main(String[] args) {
        Runnable13_6 runnable13_6 = new Runnable13_6();

        new Thread(runnable13_6,"小明").start();
        new Thread(runnable13_6,"小红").start();
        new Thread(runnable13_6,"小雷").start();

    }
}

Callable

静态代理模式

package demo13;

/**
 * @ClassName Runnable13_7
 * Description T0D0
 * @Author WangYuanpeng
 * Date 2021/4/2 16:13
 * Version 1.0
 **/


    public class Runnable13_7 {
        public static void main(String[] args) {
            //代理对象  代理 真实对象
            You you = new You();
            new WeddingCompany(you).happyMarry();
        }
    }

    //真实对象:你
    class You implements Marry{

        @Override
        public void happyMarry() {
            System.out.println("我要结婚了,好hi呦");
        }
    }


    //代理对象:婚庆公司
    class WeddingCompany implements Marry{

        //婚庆需要有你这个人 , 代理对象需要代理一个真实对象
        private Marry you;

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

        @Override
        public void happyMarry() {
            before();
            this.you.happyMarry();//你要结婚
            after();
        }

        private void before() {
            System.out.println("结婚之前,布置洞房");
        }
        private void after() {
            System.out.println("结婚之后,催你收钱");
        }

    }


    //共同的接口:结婚
    interface Marry{
        void happyMarry();
    }


//结婚之前,布置洞房
//我要结婚了,好hi呦
//结婚之后,催你收钱



lambda

love = (int a) -> {
System.out.println(“我喜欢lambda” + a);

package demo13;

/**
 * @ClassName Lamda13_10
 * Description T0D0
 * @Author WangYuanpeng
 * Date 2021/4/2 19:16
 * Version 1.0
 **/

public class Lambda13_10 {


    //静态内部类
    static class love1 implements Ilove{

        @Override
        public void lam(int a) {
            System.out.println("我喜欢lambda" + a);
        }
    }

    public static void main(String[] args) {

        //局部内部类
        class love2 implements Ilove{

            @Override
            public void lam(int a) {
                System.out.println("我喜欢lambda" + a);
            }
        }

        Ilove love = new love();   //多态
        love.lam(1);

        love = new love1();
        love.lam(2);

        love = new love();
        love.lam(3);

        //匿名内部类
        love = new Ilove() {
            @Override
            public void lam(int a) {
                System.out.println("我喜欢lambda" + a);
            }
        };
        love.lam(4);

        //lambda表达式
        love = (int a) -> {
            System.out.println("我喜欢lambda" + a);
        };
        love.lam(5);


    }
}

//函数式接口
interface Ilove{
    void lam(int a);
}


//外部类
class love implements Ilove{

    @Override
    public void lam(int a) {
        System.out.println("我喜欢lambda" + a);
    }
}

sleep 当地时间 和倒计时

package demo13;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.SimpleFormatter;

/**
 * @ClassName Sleep13_12
 * Description T0D0
 * @Author WangYuanpeng
 * Date 2021/4/2 19:54
 * Version 1.0
 **/

public class Sleep13_12  {

    public static void main(String[] args) {

//        Sleep13_12 sleep13_12 = new Sleep13_12();
//        sleep13_12.test();

        //系统当前时间
        Date startTime = new Date(System.currentTimeMillis());

        while (true){
            try {
                Thread.sleep(1000);
                System.out.println(new SimpleDateFormat("yy:MM:dd:HH:mm:ss").format(startTime));
                startTime = new Date(System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }



        }

    }
    
//倒计时
    public void test(){
        int i = 10;
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i--);
            if (i<0){
                break;
            }

        }

    }

}

线程状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ePNY864R-1617800035530)(C:\Users\WangYuanpeng\AppData\Roaming\Typora\typora-user-images\image-20210402212621590.png)]

线程同步机制

形成条件:队列和锁[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p419YytI-1617800035532)(file:///C:\Users\WangYuanpeng\AppData\Local\Temp\SGPicFaceTpBq\11428\1EA0F7B8.png)]synchronized

会损失性能

同步方法 synchronized关键字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值