Java多线程随笔(1):线程的实现

目录

进程和线程的基本概念

线程创建的三种方式

1. 继承Thread类

2. 实现Runnable接口

3. 实现Callable接口()

探究Thread类

1. lambda 表达式

2. 静态代理模式


进程和线程的基本概念

 

进程是程序执行和资源分配的基本单位,线程是CPU调度和执行的基本单位;

 

线程创建的三种方式

 

1. 继承Thread类

关于Thread类:Thread类继承Object类,同时实现了Runnable接口。

实现方法:①声明一个类,继承Thread类,②重写run()方法,③创建线程对象,调用start()方法。

不建议使用:OOP单继承局限性。

public class TestThread1 extends Thread {
    @Override
    public void run() {
        //重写run()方法
    }

    public static void main(String[] args){
        TestThread1 t = new TestThread1();
        t.start();
    }
}

举例:网图下载

package demo.thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

public class TestThread1 extends Thread {
    private String url;
    private String fileName;

    public TestThread1(String url, String fileName){
        this.url = url;
        this.fileName = fileName;
    }

    //执行主体
    @Override
    public void run() {
        //重写run()方法
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url, fileName);
        System.out.println(fileName+"已经下载完成");
    }

    public static void main(String[] args){
        TestThread1 t1 = new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1600972938327&di=d93212c74560e6ecb7d766a1452a2a87&imgtype=0&src=http%3A%2F%2Fimage.namedq.com%2Fuploads%2F20190511%2F19%2F1557575056-oBLizxVyGb.jpg", "1.jpg");
        TestThread1 t2 = new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1600973064432&di=bdb1cfcf3b886920ddfbfe2329287f59&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn18%2F217%2Fw640h377%2F20181112%2F81e4-hnstwwr1625807.jpg", "2.jpg");
        TestThread1 t3 = new TestThread1("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1600973064432&di=6f9d342fd1e57de39db03f283299ffc6&imgtype=0&src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201906%2F25%2F20190625105243_xwgss.thumb.400_0.jpg", "3.jpg");

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

//下载器类
class WebDownloader{
    public void downloader(String url, String fileName){
        try {
            FileUtils.copyURLToFile(new URL(url), new File(fileName));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("dowloader() Exception");
        }
    }
}

 

2. 实现Runnable接口

实现方法:①声明一个类,实现Runnable接口,②重写run()方法,③创建实现类对象,创建代理类对象,调用start()方法。

建议使用:避免单线程的局限性,方便同一个对象被多个线程使用。

public class TestThread2 implements Runnable{
    @Override
    public void run() {
        //重写run方法
    }
    public static void main(String[] args){
        TestThread2 t2 = new TestThread2();
        Thread t = new Thread(t2);
        t.start();
    }
}

举例:模拟龟兔赛跑

public class Race implements Runnable {

    private static String winner;

    @Override
    public void run() {

        for (int i = 0; i <= 1000; i++) {
            boolean flag = gameOver(i);
            if(flag){
                break;
            }
            if(i%100 == 0){
                System.out.println(Thread.currentThread().getName()+"已经跑了"+i+"米");
            }
            if(i == 500 && Thread.currentThread().getName().equals("兔子")){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    boolean gameOver(int distance){
        if(winner != null)
            return true;
        else {
            if(distance>=1000){
                winner = Thread.currentThread().getName();
                System.out.println("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();
    }
}

 

3. 实现Callable接口()

实现方法:①声明一个类,实现Callable接口,②重写call方法,③主线程创建执行服务,④提交执行,⑤获取call方法的返回值,⑥关闭服务 

优点:①可以定义返回值,②可以抛出异常

import java.util.concurrent.*;

public class TestCallable implements Callable {
    @Override
    public Object call() throws Exception {
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable testCallable = new TestCallable();
        //创建执行任务
        ExecutorService service = Executors.newFixedThreadPool(1);
        //提交执行
        Future<Boolean> result1 = service.submit(testCallable);
        //获取结果
        boolean r1 = result1.get();
        //关闭服务
        service.shutdownNow();
    }
}

 

探究Thread类

 

1. lambda 表达式

优势:

  •  避免匿名内部类定义过多
  • 可以让代码更简洁
  • 去掉没有意义的代码,只留下核心逻辑

函数式接口:任何接口,如果只包含一个抽象方法,那么他就是一个函数式接口。

对于函数式接口,我们可以通过lambda表达式来创建接口的对象。

Runnable接口只有符合函数式接口,因此可以在实现Runnable接口时直接使用Lambda表达式。 

 各种接口实现举例:

public class Lambda {

    //3.静态内部类
    static class Work2 implements Person{
        @Override
        public void career(String str) {
            System.out.println(str);
        }
    }

    public static void main(String[] args) {

        //4.局部内部类
        class Work3 implements Person{
            @Override
            public void career(String str) {
                System.out.println(str);
            }
        }

        //5.匿名内部类
        Person person4 = new Person() {
            @Override
            public void career(String str) {
                System.out.println(str);
            }
        };

        //6.Lambda表达式
        Person person5 = (str)->{
            System.out.println(str);
        };

        Person person1 = new Work1();
        Person person2 = new Work2();
        Person person3 = new Work3();

        person1.career("student");
        person2.career("doctor");
        person3.career("teacher");
        person4.career("professor");
        person5.career("officer");


    }
}

//1.定义函数接口
interface Person{
    void career(String str);
}

//2.类
class Work1 implements Person{
    @Override
    public void career(String str) {
        System.out.println(str);
    }
}

 

2. 静态代理模式

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

好处:代理对象可以做很多真实对象做不了的事情,真实对象专注做自己的事情。

以婚庆公司举例:

public class StaticProxy {

    public static void main(String[] args) {

        You you = new You();

        new WeddingCompany(you).happyMarry();
    }

}

interface Marry{
    void happyMarry();
}

class You implements Marry{
    @Override
    public void happyMarry() {
        System.out.println("happy marry");
    }
}

class WeddingCompany implements Marry{

    private You target;

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

    @Override
    public void happyMarry() {

        before();
        this.target.happyMarry();
        after();
    }

    public void  before(){
        System.out.println("布置婚礼");
    }

    public void after() {
        System.out.println("收尾款");
    }
}

在Java中线程的设计就使用了静态代理设计模式,其中自定义线程类实现Runable接口,Thread类也实现了Runalbe接口,在创建子线程的时候,传入了自定义线程类的引用,再通过调用start()方法,调用自定义线程对象的run()方法。实现了线程的并发执行。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页