java学习day31---(多线程详解01)

多线程

线程状态

新建状态:创建一个线程对象,但还未开启线程

就绪状态:具备了抢夺cpu执行权的权利

运行状态:抢到cpu,在执行代码块,yield方法退回就绪状态

死亡状态:执行完代码,或者代码中有异常 被抛出,stop手动结束

阻塞状态:

Scanner、sleap()方法休眠

阻塞状态没有cpu抢夺权

线程名称

在run()中this.getName(),获得当前线程名称

线程对象.setName(),可以设置线程名称

获取线程名称通用方法:

使用currentThread()方法,返回当前调用run()线程的引用

然后在调用getName()方法,就可以获取调用线程的名称

 @Override
   public void run() {
       Thread thread = Thread.currentThread();
       String name = thread.getName();
       System.out.println("线程1!");
  }

线程调度方法

Thread.stop()是终止当前线程,在run()方法中调用,和线程中出现异常再被终止是一样的

System.exit()是停止虚拟机


Thread.yield()方法直接让当前线程回到就绪状态

Thread.sleap()方法是让线程休眠


线程名.join()方法,可以使当前线程执行完毕,cpu才会被别的线程占用,方法要紧跟的线程开启之后

守护线程

概念:伴随着用户线程的产生而开始,只要有用户线程,就会开启

线程名.setDaemon() 声明此线程是守护线程

实现线程的第三种方式

实现有返回值的线程

使用Callable接口的抽象call()方法,call()方法带有返回值

FutureTask<>类也是一个Thread类,传入的参数是Callable接口的实现类对象

对象名.get()获得线程的返回值,这个方法直接阻塞了别的线程,当拿到这个线程的返回值才让别的线程去抢夺cpu

线程安全问题

造成安全问题的原因

1.有多线程环境

2.多个线程共享一个线程任务

3.变量的run()方法的成员变量,多个线程共享一个成员变量

4.多个线程对同一个成员变量进行操作

5.线程任务不是原子的 原子:不可拆分的 当这个线程没有执行完却又被别的线程抢占了cpu

解决安全问题的方法(锁的运用)

同步代码块

同步代码块没有执行完之前,别的线程不能抢占cpu

语法synchronized(){} 参数是传入一个锁:Object o=new Object();

锁有两种状态:1.加锁 2.解锁

线程进入代码块加锁,出代码块解锁

同步方法

使用一个方法进行加锁解锁,原理同上

语法:public synchronezed void fun(){}

这个方法中的代码块执行完,才会空出cpu

都需要在成员变量中定义一个锁

同步锁对象

自己创建一个锁对象,手动加锁解锁

ReentrantLock类,一个锁类

lock()加锁;uplock解锁

线程安全的类集合

StringBffer是线程安全的,被synchronized修饰

Vector hashtable 等都提供了同步机制,被synchronized修饰

死锁

共用了2个锁,并且嵌套

唤醒机制

线程与线程之间不只有竞争关系,还有协作关系

线程之间通讯

同步:同一时刻,一个线程在执行,另一个线程不执行(合作关系)

异步:同一时刻,两个线程都在执行 (竞争关系)

要想保证两个线程同步

必须加同步机制,两个线程共享同一个锁


通讯机制(等待唤醒)

o.wait()等待

1.释放锁对象 2.放弃cpu占有权 3.不具备抢夺cpu能力 4.让当前线程在此等待,等待被唤醒

o.notify()唤醒 1.唤醒在此锁对象上等待的线程对象 2.不是立即解锁,而是把当前的同步代码块执行完了之后,在释放锁

posted @ 2021-08-11 11:35  墨衣i  阅读(34)  评论(0)    收藏  举报