美文网首页
多线程入门

多线程入门

作者: Summer2077 | 来源:发表于2020-07-21 19:48 被阅读0次

重点:

  • 线程的实现

  • 线程的同步

Process(进程)和 Thread(线程)

进程中有线程,真正执行的是线程

线程的创建

  • Thread class (重点) 继承Tread类
  • Runnable 接口 (重点) 实现Runnable接口
  • Callable 接口 (了解)

1.继承Tread类:

1.继承Thread类

2.重写run()方法

3.创建对象,调用start()来启动

public class ThreadDemo01 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("我在学习多线程---"+i);
        }
    }

    public static void main(String[] args) {

        ThreadDemo01 threadDemo01 = new ThreadDemo01();
        threadDemo01.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("我在涨知识---"+i);
        }
    }
    
}

结果为:

Thread01.png

总结:线程开启不一定会执行没做过是有cpu来调度执行的

练习:下载网图

public class TestThread extends Thread {

    private String url ;
    private String name;

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

    @Override
    public void run() {
        WebDownLoader webDownLoader = new WebDownLoader();
        webDownLoader.downLoad(url,name);
        System.out.println("下载了文件为:"+name+"文件的URL为:"+url);
    }

    public static void main(String[] args) {
        TestThread t1 = new TestThread("http://www.pppnut.cn/blog-image/study-DesignPattern/Factory/1.jpg","1.jpg");
        TestThread t2 = new TestThread("http://www.pppnut.cn/blog-image/study-DesignPattern/Factory/2.jpg","2.jpg");
        TestThread t3 = new TestThread("http://www.pppnut.cn/blog-image/study-DesignPattern/Factory/3.jpg","3.jpg");
        t1.start();
        t2.start();
        t3.start();
    }
}


//下载器
class WebDownLoader{
//下载方法
    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异常,downLoad方法出现问题");
        }
    }
}

结果:

ThreadTest.png

2.实现Runnable接口

1.实现Runnable接口

2.重写run()方法

3.创建实现对象,创建代理对象,调用start()方法

package com.summer.Thread;

public class ThreadDemo03 implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("我在学习多线程---"+i);
        }
    }

    public static void main(String[] args) {
//        创建实现对象
        ThreadDemo03 threadDemo03 = new ThreadDemo03();
//        创建代理对象
        Thread thread = new Thread(threadDemo03);
//        调用start()方法启动线程
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("我在涨知识---"+i);
        }
    }
}

总结:runable接口来实现多线程,需要将实现对象丢入Thread中进行代理

为是什么会Thread有代理?为什么会用runable接口来实现?

应为runable是一个接口,其中只定义了一个run()方法,我们对run()进行了重写,但是我们就光靠一个run()方法是没有办法启动我们的线程的这个时候就要借助Thread中start()方法。所以就会出现上面的将runable实现类丢给了Thread。这样的做的话我们还可以吧这个runable丢给其他的类,去实现其他的功能。

runable避免了oop单继承的局限性,灵活,方便同一个对象被多个线程使用。

练习

1.抢票案例

public class ThreadDemo04 implements Runnable {

    private int ticketNum = 10;

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

    }

    public static void main(String[] args) {
        ThreadDemo04 threadDemo04 = new ThreadDemo04();
        new Thread(threadDemo04,"小明").start();
        new Thread(threadDemo04,"老师").start();
        new Thread(threadDemo04,"黄牛").start();
    }
}`

结果:

并发入门.png

问题:多个线程同时操作同一个资源,会造成资源的紊乱。

1.龟兔赛跑的案例

package com.summer.Thread;

public class ThreadTestRace implements Runnable {

    private String winner;

    @Override
    public void run() {

        if (Thread.currentThread().getName().equals("兔子")){
            for (int i = 0; i <= 500; i=i+10) {
                if (i%120==0){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                if (gameOver(i)){
                    System.out.println("获胜者是"+winner);
                    break;
                }else {
                    System.out.println(Thread.currentThread().getName()+"走了"+i+"步数");
                }
            }
        }else {
            for (int i = 0; i <= 500; i++) {
                if (gameOver(i)){
                    System.out.println("获胜者是"+winner);
                    break;
                }else {
                    System.out.println(Thread.currentThread().getName()+"走了"+i+"步数");
                }
            }
        }
    }

    public boolean gameOver(int step){
        if(winner!=null){
            return true;
        }else if(step>=500){
            winner = Thread.currentThread().getName();
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        ThreadTestRace threadTestRace = new ThreadTestRace();
        new Thread(threadTestRace,"兔子").start();
        new Thread(threadTestRace,"乌龟").start();
    }
}

实现Callable接口(了解)

  1. 创建服务
  2. 提交线程
  3. 获取结果
  4. 获取结果
public class ThreadDemo05 implements Callable<Boolean> {
   private String url ;
   private String name;

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

   @Override
   public Boolean call() throws Exception {
       WebDownLoader webDownLoader = new WebDownLoader();
       webDownLoader.downLoad(url,name);
       System.out.println("下载了文件为:"+name+"文件的URL为:"+url);
       return true;
   }

   public static void main(String[] args) throws ExecutionException, InterruptedException {
       ThreadDemo05 t1 = new ThreadDemo05("http://www.pppnut.cn/blog-image/study-DesignPattern/Factory/1.jpg","1.jpg");
       ThreadDemo05 t2 = new ThreadDemo05("http://www.pppnut.cn/blog-image/study-DesignPattern/Factory/2.jpg","2.jpg");
       ThreadDemo05 t3 = new ThreadDemo05("http://www.pppnut.cn/blog-image/study-DesignPattern/Factory/3.jpg","3.jpg");
       //创建服务
       ExecutorService ser = Executors.newFixedThreadPool(3);

       //提交线程
       Future<Boolean> r1 = ser.submit(t1);
       Future<Boolean> r2 = ser.submit(t2);
       Future<Boolean> r3 = ser.submit(t3);

       //获取结果
       Boolean res1 = r1.get();
       Boolean res2 = r2.get();
       Boolean res3 = r3.get();

       //关闭线程池
       ser.shutdown();
   }
}

//下载器
class WebDownLoader{
   //下载方法
   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异常,downLoad方法出现问题");
       }
   }
}

callable 的好处:

  • 可以定义返回值类型
  • 可以抛出异常

静态代理模式

真实对象和代理对象都要实现同一个接口。

代理对象代理真实角色。

好处:

  • 代理对象可以做很多真实对象做不了的事情
  • 真实对象专注做自己的事情

相关文章

网友评论

      本文标题:多线程入门

      本文链接:https://www.haomeiwen.com/subject/asmwkktx.html