多线程学习

多线程

线程就是独立的执行路径

一个进程可以有多个线程

但是这些线程其实都是模拟出来的 真正的多线程是指cpu有多个

即使是在有一个cpu的情况下,在同一时间点 cpu只能执行一个代码,但因为cpu执行效率高 时间短,所以我们就会chans同时执行的错觉

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

2.线程的创建方式

继承Thread类(重点)

1.继承Thread类 然后重写run方法

2.创建一个thread的对象 调用start方法开启多线程

public class TestThread extends Thread {
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i <100 ; i++) {
            System.out.println("run"+i);
        }
    }

    public static void main(String[] args) {
        //创建线程对象 调用start方法 开启线程
        TestThread testThread = new TestThread();
        testThread.start();
        //main线程,主线程
        for (int i = 0; i <10000 ; i++) {
            System.out.println("main"+i);
        }
    }
}

程序运行结果可以看出 显示运行了main方法

但在main方法运行的中间也开了run方法的执行,两个线程实际上是同时在运行

运行的先后顺序是cpu调度的

小实例

//练习Thread,实现多线程同步下载图片
public class TestThread2 extends Thread{
    private  String url;//网络图片地址
    private  String name;//保存的文件名

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

    @Override
    public void run() {
        WebDonload webDonload = new WebDonload();
        webDonload.download(url,name);
        System.out.println("下载的文件名为"+name);
    }

    public static void main(String[] args) {
        TestThread2 testThread1 = new TestThread2("http://img3.imgtn.bdimg.com/it/u=2534506313,1688529724&fm=26&gp=0.jpg","1");
        TestThread2 testThread2 = new TestThread2("http://img4.imgtn.bdimg.com/it/u=1280325423,1024589167&fm=26&gp=0.jpg","2");
        TestThread2 testThread3 = new TestThread2("http://t7.baidu.com/it/u=888206991,1760071208&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=cc5d57a46142087a2aa2124099bc6eec","3");
        testThread1.start();
        testThread2.start();
        testThread3.start();
    }
}
//类加载器 程序运行时加载 下载器
class  WebDonload{
    public void download(String url,String name){//获取网络图片的方法
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("io异常");
        }
    }
}

从结果发现并不是按照1,2,3的顺序进行下载的

实现Runnable接口(重点)

1.创建一个类去实现Runnable接口

2.重写run方法

3.创建一这个类的一个对象

4.用代理模式将这个对象传入Thread中然后.start

public class TestThread3 implements  Runnable{
    public void run() {
        for (int i = 0; i <300 ; i++) {
            System.out.println("这里是run"+i);
        }
    }

    public static void main(String[] args) {
        //创建runnable的对象
        TestThread3 testThread3 = new TestThread3();
        //创建一个thread对象
        new Thread(testThread3).start();
        for (int i = 0; i <2000 ; i++) {
            System.out.println("这里是main方法"+i);
        }

    }
}

推荐使用这一种方法

避免单继承的局限性,灵活方便,方便一个对象被多个线程启用

例子二 龟兔赛跑

//多线程模拟龟兔赛跑
public class Race implements Runnable {
    private static int race;
    private  static String winner;
    public void run() {
        //模拟龟兔的赛跑步数
        for (int i = 0; i <=100 ; i++) {
            if (Thread.currentThread().getName().equals("龟") && i%10==0){
                try {
                    Thread.sleep(15);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //判断比赛是否结束
            boolean flag=winner(i);
            if (flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }
    //判断谁先到达了100
    public boolean winner(int step){
        if (winner!=null) {
            return true;
        }
        else if (step==100){
             winner = Thread.currentThread().getName();
            System.out.println("the winner is"+winner);
            return true;
        }
            return false;
        }

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

实现Callable接口(了解)

静态代理

1.两个类都实现了同一个接口

2.其中的一个类能调用的方法更多

3.调用这个类去实现这个另一个类实现不了的方法

叫做代理

真实例子:结婚

​ 你们要结婚

​ 婚庆公司要帮你结婚

​ 你们两个人办不下来结婚这个方法(布置,流程)

​ 找到婚庆公司帮你们结婚

​ 这就是代理了

多线程中的静态代理

 public static void main(String[] args) {
     //创建runnable的对象
        TestThread3 testThread3 = new TestThread3();
        //创建一个thread对象
        new Thread(testThread3).start();

你可能感兴趣的:(多线程学习)