多线程复习

 一. 线程与进程的区别

总结: 进程是所有线程的集合, 每一个线程是进程中的一条执行路劲


多线程优点:  提高程序效率

应用场景: 分批发送短信

二 多线程创建方式

1.继承Thread类 , 重写run方法

class CreateThread extends Thread {

// run方法中编写 多线程需要执行的代码

publicvoid run() {

for (inti = 0; i< 10; i++) {

System.out.println("i:" + i);

}

}

}

2.实现Runnable接口, 重写run方法
class CreateRunnable implements Runnable {

 

@Override

publicvoid run() {

for (inti = 0; i< 10; i++) {

System.out.println("i:" + i);

}

}

3. 使用匿名内部类

Thread thread = new Thread(new Runnable() {

public void run() {

for (int i = 0; i< 10; i++) {

System.out.println("i:" + i);

}

}

});

 thread.start();

 System.out.println("-----多线程创建结束-----");


5.4使用继承Thread类还是使用实现Runnable接口好?

使用实现Runnable 接口好, 原因是实现了接口还可以继续继承, 继承了类不能再继承.


开启执行现场是start 方法 , run是实例的调用方法


              

七、多线程运行状态

线程从创建,运行到结束总是处于一下五个状态之一: 新建任务, 就绪状态, 运行状态, 阻塞状态以及死亡状态.

7.1 新建状态

当一个线程处于新生状态时, 程序还没有开始运行线程中的代码.

新生态: new Thread(r) ,线程还没有开始运行, 此时线程处于在新建状态

7.2 就绪状态

启动线程调用start()方法,start()方法创建线程运行的系统资源,并调度运行run()方法.当start()方法返回后, 线程处于就绪状态.             

处于就绪状态的线程不一定立即运行run()方法,线程还必须同其他线程竞争cpu时间,只有获得cpu时间才可以运行线程


7.3 运行状态

当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.

7.4 阻塞状态

线程运行过程中,可能由于各种原因进入阻塞状态:

1 > 线程通过调用sleep 方法进入睡眠状态;

2> 线程调用一个在I/O 上被阻塞的操作, 即该操作在输入输出操作完成之前不会返回到它的调用者

3>线程试图得到一个锁,而该锁正被其他线程持有;

4>线程正在等待某个触发条件;

7.5 死亡状态

有两个原因导致线程死亡:

1) run 方法正常退出而自然死亡;

2)一个未捕获的异常终止了 run 方法而使线程猝死

2.1 为什么有线程安全问题?

    当多个线程同时共享, 同一个全局变量或者静态变量,做写操作时,可能或发生数据冲突问题,也就是线程安全问题,但是做读操作是不会发生的.

例如现在一个静态方法和一个非静态静态怎么实现同步?

答:

同步函数使用this锁

静态同步函数使用字节码文件,也就是类.class


什么是多线程死锁?

答:

同步中嵌套同步

什么是多线程之间的通讯?

多线程之间的通讯,其实就是多线程在操作同一个资源,但是操作的动作不同

wait(), notify() notifyAll() 方法

wait() notify() notifyAll() 三个定义在object类里的方法,可以用来控制线程状态.这三个方法最终调用的都是jvm 级的native方法, 随着jvm运行平台的不同可能有差异

如果对象掉了 wait方法就会使持有对象的线程把该对象的控制权交出去,如何处于等待状态

如果对象调用notify 方法就会通知某个正在等待这个对象的控制权的线程可以继续运行

如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行

wait 与sleep 区别?

sleep()方法属于Thread类中, wait()属于Object类中

sleep()程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持,当指定时间到了优惠自动回复运行状态

sleep()使用 线程不会释放锁

wait()使用 线程会释放锁

Lock写法:

Lock lock = new ReentrantLock();

lock.lock();

try{}finally{lock.ublock();}


ReentrantLock

ReentrantLock是一个可重入的互斥锁,ReentrantLock由最近成功获取锁,还没有释放的线程所拥有,当锁被另一个线程拥有时,调用lock的线程可以成功获取锁。如果锁已经被当前线程拥有,当前线程会立即返回

Lock 接口与 synchronized 关键字的区别
Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。
*Lock 接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。

Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。

 

join 作用是让其他线程变为等待

yield 方法 :
Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果)

yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会


因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。
结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。
 

线程三大特征

原子性  可见性    有序性

原子性: 一个或多个操作.要么全部执行并且执行的过程中不会被其他因素打断,要么就不执行,以保证数据一致,线程安全

可见性: 当多个线程访问同一变量时,一个线程修改了这个变量的值, 其他线程能够立即看到修改的值

有序性:  线程 按照程序先后顺序执行

java内存模型

 

 

线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存存储了该线程以读/写共享变量的副本

总结: java内存模型简称:jvm ,定义了一个线程对另一个线程可见, 共享变量放在主内存中, 每个线程都有自己的本地内存, 但多个内存同时访问一个数据的时候, 可能本地内存没有及时刷新到主内存, 所以可能发生线程安全问题

四 Volatile

作用: Volatile 关键字的作用是变量在多个线程之间可见

解决办法是有Volatile 关键字将解决线程之间可见性,强制线程每次读取该值的时候都去"主内存"中取值

volatile 属于非原子性

ThreadLoca

  ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己的局部变量

  当使用ThreadLocal 维护变量时, ThreadLocal为每个使用该变量的线程提供独立的变量副本, 

所以每一个线程都可以独立改变自己的副本,而不会影响其他线程所对应的副本

ThreadLocal接口:

void set(Object vlaue)  设置当前线程的线程局部变量的值;

public Object get() 该方法返回当前线程所对应的线程局部变量

public void remove() 将当前的线程局部变量的值删除,减少内存的占用

protected Object initialValue() 返回该线程局部变量的初始值

线程池四种创建方式

newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程, 若无可回收, 则新建线程.

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待

newScheduledThreadPool 创建一个定长线程池, 支持定时及周期性任务执行

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序(FIFO,LIFO)执行

什么是多线程之间通讯?

多线程之间通讯其实就是多个线程在操作同一个资源, 只是动作不同

wait  notify  notifyAll  最终都是控制jvm的native方法 , 平台不同运行略有差异

如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。

如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。

如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

注意:一定要在线程同步中使用,并且是同一个锁的资源

wait 和  sleep 区别

sleep   属于  Thread  类     不释放锁   利用CPU暂停执行指定的时间进行暂停

wait     属于  Object  类                        释放锁      线程进入等待锁定池等待

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你今天学习了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值