多线程,线程简介,线程的创建,静态代理,Lamda表达式

多线程

线程简介

任务,进程,线程,多线程

多任务:在现实生活中同时做多件事,看起来是多个任务都在做,实际上我们的大脑在同一时间只做了一件事情

线程:线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

在Java Web中要注意,线程是JVM级别的,在不停止的情况下,跟JVM共同消亡,就是说如果一个Web服务启动了多个Web应用,某个Web应用启动了某个线 程,如果关闭这个Web应用,线程并不会关闭,因为JVM还在运行,所以别忘了设置Web应用关闭时停止线程。

进程:一个进程可以有多个线程,如视频中的声音,图像,字幕等。进程是操作系统结构的基础;是一次程序的执行;是一个程序及其数据在处理机上顺序执行时所发生的活动。操作系统中,几乎所有运行中的任务对应一条进程(Process)。一个程序进入内存运行,即变成一个进程。进程是处于运行过程中的程序,并且具有一定独立功能。描述进程的有一句话非常经典——进程是系统进行资源分配和调度的一个独立单位。

进程是系统中独立存在的实体,拥有自己独立的资源,拥有自己私有的地址空间**。**进程的实质,就是程序在多道程序系统中的一次执行过程,它是动态产生,动态消亡的,具有自己的生命周期和各种不同的状态。进程具有并发性,它可以同其他进程一起并发执行,按各自独立的、不可预知的速度向前推进。

(注意,并发性(concurrency)和并行性(parallel)是不同的。并行指的是同一时刻,多个指令在多台处理器上同时运行。并发指的是同一时刻只能有一条指令执行,但多个进程指令被被快速轮换执行,看起来就好像多个指令同时执行一样。)

进程由程序数据进程控制块三部分组成。

普通方法调用和多线程

在这里插入图片描述

Process与Thread

  • 说起进程,就不得不说下程序。程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
  • 而进程则是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单位
  • 通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程是CPU调度和执行的的单位。

注意:很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器。如果是模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所以就有同时执行的错局。

线程的创建和启动

  • Thread class,继承Thread类
  • Runnable接口,实现Runnable接口
  • Callable接口,实现Callable接口

1、继承Thread类创建线程类

通过继承Thread类创建线程类的具体步骤和具体代码如下:

• 定义一个继承Thread类的子类,并重写该类的run()方法;

• 创建Thread子类的实例,即创建了线程对象;

• 调用该线程对象的start()方法启动线程。

class SomeThead extends Thraad   { 
    public void run()   { 
     //do something here  
    }  
 } 
 
public static void main(String[] args){
 SomeThread oneThread = new SomeThread();   
  //步骤3:启动线程:   
 oneThread.start(); 
}

案列:下载网图

public class TestThread extends Thread {
    //
    private String url;
    private String name;

    public TestThread(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) {
        TestThread t1 = new TestThread("","1.jpg");
        TestThread t2 = new TestThread("","2.jpg");
        TestThread t3 = new TestThread("","3.jpg");

        t1.start();
        System.out.println("执行了t1");
        t2.start();
        System.out.println("执行了t2");
        t3.start();
        System.out.println("执行了t3");
    }
}

//下载图片
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("downloader方法出现异常");
        }
    }

}

2、实现Runnable接口创建线程类

通过实现Runnable接口创建线程类的具体步骤和具体代码如下:

• 定义Runnable接口的实现类,并重写该接口的run()方法;

• 创建Runnable实现类的实例,并以此实例作为Thread的target对象,即该Thread对象才是真正的线程对象。

class SomeRunnable implements Runnable   { 
  public void run()   { 
  //do something here  
  }  
} 
Runnable oneRunnable = new SomeRunnable();   
Thread oneThread = new Thread(oneRunnable);   
oneThread.start(); 

案列:龟兔赛跑

public class Race implements Runnable{
//winner:只有一个胜利者
private static String winner;

@Override
public void run() {
    //赛道
    for (int step = 1; step <= 101; step++) {

        //兔子休眠
        if (Thread.currentThread().getName().equals("兔子") && step % 50==0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //判断比赛是否结束
        boolean flag = gameOver(step);
        if (flag){
            break;
        }

        System.out.println(Thread.currentThread().getName()+"跑了"+ step +"步");

    }
}

//判断比赛是否结束
private boolean gameOver(int step){
    if (winner!=null){ //如果存在胜利者
        return true;
    }
    if (step>=100){  //如果跑到了比赛结束
        winner = Thread.currentThread().getName();
        System.out.println("比赛结束");
        System.out.println("胜利者----->"+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和Future创建线程

通过Callable和Future创建线程的具体步骤和具体代码如下:

• 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
• 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
• 使用FutureTask对象作为Thread对象的target创建并启动新线程。
• 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值其中,Callable接口(也只有一个方法)定义如下:

public interface Callable   { 
  V call() throws Exception;  
 } 
  步骤1:创建实现Callable接口的类SomeCallable;   
  步骤2:创建一个类对象: 
      Callable oneCallable = new SomeCallable(); 
  步骤3:由Callable创建一个FutureTask对象:   
    FutureTask oneTask = new FutureTask(oneCallable); 
  注释: FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了 Future和Runnable接口。 
  步骤4:由FutureTask创建一个Thread对象:   
    Thread oneThread = new Thread(oneTask);   
  步骤5:启动线程:  
    oneThread.start(); 

静态代理

把不想做的,琐碎的事找个代理做

public class StaticProxy {
    public static void main(String[] args) {
        //代理对象  代理 真实对象
        You you = new You();
        you.happyMarry();
        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();
}

Lamda表达式

  • λ希腊字母表中排序第十一位的字母,英语名称为Lambda
  • 避免匿名内部类定义过多
  • 其实质属于函数式编程的概念
public class Test03 {
    public static void main(String[] args) {
        ILove love = new Love();
        love.lambda(1);

        //匿名内部类
        love = new ILove() {
            @Override
            public void lambda(int a) {
                System.out.println("我开始喜欢lambda了...."+a);
            }
        };
        love.lambda(2);


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


        //简化1: 去掉括号
        love = a->{
            System.out.println("我开始喜欢lambda了...."+a);
        };
        love.lambda(4);


        //简化2:去掉花括号
        love = a->System.out.println("我开始喜欢lambda了...."+a);

        love.lambda(5);

    }
}


//函数式接口
interface ILove{
    void lambda(int a);
}

class Love implements ILove{
    @Override
    public void lambda(int a) {
        System.out.println("我开始喜欢lambda了...."+a);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值