Java 多线程学习笔记11.22

线程简介

程序,程序是指令和数据的有序集合,静态的概念。

进程则是齿形程序的一次执行过程,是个动态概念,是系统资源分配的单位。

一个进程可以包含若干个线程,线程是CPU调度和执行的单位。

很多多线程是模拟出来的,因为切换很快,所以有同时执行的错觉。

真正的多线程,是多个cpu。

注意:

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

不能认为干预多个线程的先后顺序。

对同一份资源操作,会存在资源抢夺的问题,需要加入并发控制。

线程会带来额外的开销。


线程实现(重点)

1.线程创建(三种创建方式)

Thread class,继承Thread类(重点)

Runnable接口,实现Runnable接口(重点)

Callable class,实现Callable接口

2.Thread类

使用

自定义线程类继承Thread类

重写run()方法

创建一个线程对象,调用start方法开启线程

如下所写;

public class Application extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 2000; i++) {
            System.out.println("AAA");
        }
    }

    public static void main(String[] args) {
        Application one = new Application();
        one.start();
        for (int i = 0; i < 2000; i++) {
            System.out.println("BBB");
        }
    }
}

3.Runnable接口(可以多继承)

实现runnable接口,

重写run方法,

执行线程丢入runnable接口实现类,调用start方法。

public class Application implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("看代码呢");
        }
    }

    public static void main(String[] args) {
        Application application = new Application();
        new Thread(application).start();
        for (int i = 0; i < 20; i++) {
            System.out.println("玩呢");
        }
    }
}

注意:new Thread(对象,线程名称)建立一个线程对象

4.Callable接口(了解)

5.Thread类方法

Thread.sleep()延迟

Thread.currentThread().getName()得到名称

6.Lamda表达式

前提知识:匿名内部类

Ilove ilove = new Ilove(){

        public void love(){};

}

Ilove为接口

优势:可以让你的代码看起来很简洁

        去掉一堆没有意义的代码,只留下核心的逻辑

任何接口,如果只有一个抽象方法,就是函数式接口,

可以用lamada表达式创建该接口的对象。

用法:接口 名称 = () -> {};

翻译:简化了一次性使用的匿名内部类,由于接口只提供一个方法,直接()->{ } 可以书写该对象继承接口的方法

曲线救国级理解:定义了一个匿名类,并定义了接口的方法

7.静态代理模式

真实对象和代理对象要实现统一接口。

代理对象用target表示真实对象。

好处:

        代理对象可以做很多真实对象做不了的事情 

        真实对象专注做自己的事情

public class TestLamda2{
    public static void main(String[] args) {
        new WeddingPlanner(() -> System.out.println("hi")).HappyMarry();
    }
}

interface Marry{
    void HappyMarry();
}

class WeddingPlanner implements Marry{

    private Marry target;

    public WeddingPlanner(Marry target){
        this.target = target;
    }

    public void HappyMarry() {
        this.target.HappyMarry();
    }
    
}

暂时理解:传参相当于Marry target = ()->sout("hi")

与线程的联系:Thread设个Runnable的接口,(不用lamda表达)Runnable A = B,

(用lamda表达)Runnable A = ()->{ }


线程状态

 

1.停止线程(外置判断暂停)

推荐线程自己停止下来

public class TestLamda2{
    private static boolean flag = true;

    public static void main(String[] args) {
        Runnable runnable = ()->{
            int i = 0;
            while(flag){
                if(i==1000)flag=false;
                System.out.println("小线程"+i++);
            }
        };
        new Thread(runnable).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程"+i);
            if(i==900){
                stop();
                System.out.println("线程停止了");
                break;
            }
        }
    }

    static void stop(){
        flag = false;
    }
}

2.线程休眠(Thread.sleep)

模拟延迟Thread.sleep(毫秒数) 

sleep存在异常InterruptedException

sleep时间达到后线程进入就绪状态

sleep可以模拟网络延时,倒计时

每个对象都有一个锁,sleep不会释放锁

3.线程礼让(Thread.yield)

礼让线程,让当前正在执行的线程暂停,但不阻塞

讲线程从运行状态转化就绪状态

让cpu重新调度,礼让不一定成功

4.插队线程(Thread.join)

5.线程状态

类名Thread.State = XX.getState();

新生NEW,运行Runnable,延迟TIMED——WAIIING,结束TERMINATED

6.线程优先级

优先级数 1~10

线程对象.setPriority(级数)

7.守护(daemon)线程

线程分为用户线程守护线程(伴随虚拟机的开始和结束)

虚拟机必须确保用户线程执行完毕

虚拟机不用等待守护线程执行完毕(后台记录操作日志,监控内存)


线程同步(重点)

多个线程操作同一个资源

队列:线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用。

锁:为了保证数据在方法中被访问是的正确性,在访问时加入锁机制,当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可。

1.同步方法

public synchronized void methode(int args){ }

加上synchronized关键字,就能锁住该方法

默认锁的是本身.

2.同步块

synchronizded (Obj){             }

Obj表示被锁的对象(是变化的量)

3.JUC里的安全类型集合

CopyONWriteArrayList

4.死锁

解决方式,用完锁就赶紧放

5.Lock

实现类Reentranlock

使用:定义lock锁,然后推荐try{XX.lock()锁住}finally{lock,unlock解锁}


线程协作(用Obj自带的方法)

1.管程法

建立一个数组,添加生产的产品,然后消费产品,如果为NULL,就会等待

2.信号灯法

建立一个boolea,判断是否继续该线程,要不要等待


使用线程池

ExecutorService:真正的线程池接口(实现类ThreadPoolExecutor)

Executor:工具类

使用

ExecutorService service = Executors.newFixedThreadPool(大小)//创建服务,创建线程池

service.execute(线程对象)//执行

service.shutdown()//关闭连接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值