Java多线程编程与线程安全

目录:
1.线程定义及Java实现
2.线程的创建及生命周期
3.线程同步与协作
4.JDK中集合的线程安全
5.ThreadLocal与守护线程
6.线程池

一、线程定义以及Java实现
1.线程:线程是可以独立运行的一组指令集合,线程是轻量级进程,由操作系统负责调度和执行。
2.线程与进程区别:
(1)父子进程有不同的数据段,而同一个进程的多个线程共享数据空间
(2)进程可以独立运行,线程必须依存在进程中
(3)线程切换比进程快
3.多线程优点:
(1)程序响应快
Tomcat创建多个线程处理用户请求。监听线程监听用户请求,工作者线程处理业务。
(2)资源利用率高
CPU速度较其他设备运行速度快,其大部分时间是等待其他设备就绪。
在IO密集型程序中,多线程可以充分利用CPU资源,例如word打印,如果只有一个线程,在打印时不能对word有任何操作,只能等待打印结束。
GUI程序应用多线程。
4.Java线程创建方法
方法一:继承Thread类,重写run方法
public class UserThread extends Thread {
@Override
public void run() {}
}
方法二:实现Runnable接口,并且实现run方法
public class UserThread implements Runnable {
@override
public void run() {}
}
二、线程的创建及其生命周期
Thread生命周期:
1.新建状态
new 关键字创建对象后,在JVM上分配了内存
2.就绪状态
调用start方法使线程处于就绪状态,但是还未获得CPU时间,处于线程就绪队列中
3.运行状态
获得CPU时间,执行run方法。如果失去CPU资源再次变为就绪状态,等待CPU资源
4.阻塞状态
运行中的线程在wait方法,或者等待IO资源会变为阻塞状态,当引起阻塞的原因消失,再次进入就绪状态
5.消亡状态
状态转换图
三、线程同步与协作
1.线程安全问题产生原因
同一个进程的多个线程共享数据空间,并发情况下会产生脏数据。
2.线程不同步带来的问题
(1)多个线程共享一个对象(放在heap中),每个线程有各自的工作内存,当操作heap中的对象时,将对象从heap中复制到工作内存,修改后刷新到heap中,此时会产生数据错乱问题。
(2)例如一个账户中有100元,线程A减少10元,线程B增加10元,两个操作执行完后账户还是100元。当线程A操作账户时,看到100元,减去十元,此时还未刷新到主存,此时B线程拿到当前账户还是100元,执行增加操作,此时A执行完成,向主存写入90元,线程B执行完成后写入110元,导致数据错乱。
3.Synchronized
(1)方法时对象被锁定(非静态),而且一个对象只有一个锁,当线程A获取对象的锁后,其他线程无法获取此对象的锁,意味着不能进入此对象的任何synchronized方法,直到A线程释放锁。
(2)当synchronized加载static方法上,防止多个线程同时进入此方法,对此类的所有实例化对象生效。
四、JDK集合中的线程安全
1.JAVA线程常用方法
(1)sleep
让当前线程休眠一段时间(由参数指定)后进入就绪队列,等待再次获得CPU时间
(2)isAlive
判断线程是否是运行状态
(3)wait
使线程等待,由notify,notifyAll或者等待时间结束时唤醒
(4)notify
唤醒线程,唤醒等待池中的线程,随机挑选,进入就绪状态
(5)notifyAll
唤醒所有等待的线程,竞争获取锁执行
五、ThreadLocal与守护线程
1.ThreadLocal
threadlocal为每个使用该变量的线程提供独立的副本,每个线程都可以维护自己的副本,不会影响到其他线程此变量的副本
应用:
hibernate中session的获去,session是hibernate中一级缓存,一次连接需要将数据保存在session中,避免二次查询数据库,所以每个线程都需要有独立的session

private static final ThreadLocal threadSession = new ThreadLocal()
public static Session getSession() {
Session s = (Session)threadSession.get();
if(s==null) {
s = getSessionFactory().openSession();
threadSession.set(s);
}
return s;
}
2.守护线程
(1)守护线程作用
守护线程为其他线程运行提供服务,例如垃圾回收线程
当主线程退出时,守护线程还在运行,此时jvm也会退出
(2)创建方法
public final void setDaemon(boolean on)
必须在start方法之前调用
daemon创建的线程也是daemon线程
(3)应用
消息推送
拼写检查线程
六、线程池
1.concurrent包
concurrent提供一组线程安全的,高性能的并发构建方法。
2.线程池
(1)减少线程的创建和销毁次数
(2)调整线程池中工作线程的数目
(3)newSingleThreadExecutor
单线程线程池,池中只有一个线程工作
(4)newFixedThreadExecutor
固定大小线程池,池中线程达到最大则保持不变,线程异常结束则补充新线程
(5)newCachedThreadExecutor
可缓存的线程池,如果池中线程大于所需则回收,如果不够则创建新线程放入池中,数量以来JVM能够创建的数量大小
(6)newSchedualThreadPool
创建无限制的 线程池,定时周期执行任务

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值