个人对于java多线程的一些总结

1.如何创建一个线程?

 *  三种创建线程的方式,
 *  1.继承Thread类,通过重写run方法创建新的线程,并通过start执行线程
 *  2.直线Runnable接口,实现run方法,通过创建线程类的方法用start执行线程
 *  3.使用匿名类,继承Thread类,重写run方法

2.常见线程方法

  1.     Thread.sleep();
        使进程停顿一定时间
  2.     (Thread) t.join();
        等待该进程结束,才会进入到下一个进程
  3.     (Thread) t.setPriority();
        设置进程优先级,为1-10,优先级高的先执行
  4.     (Thread) t.yield();
        当前线程临时暂停,使其他线程有更多机会占用CPU资源

3.多个线程的同步问题

    int a=10000,此时有10000个线程在减1,又有10000个线程在加1,理想结果20000个进程结束之后a还是等于10000,

但实际上并不是,可能大于10000也可能小于10000。

    同步问题产生的原因:

        假设一个加进程先进入,得到a=10000,正在做增加运算时,一个减进程也进入,获取到的a也是10000,等加进程结束,

    a的结果是10001,赋值给a,减进程结束,a的结果是9999,赋值给a,最终a的结果就是9999,本来期望还原值10000,实际得到了9999,在业务上也叫做脏数据

    要解决同步问题,用到synchronized关键字

Object someObject =new Object();
synchronized (someObject){
  //此处的代码只有占有了someObject后才可以执行
}

synchronized修饰的对象单次只允许一个进程访问,即不会出现a被加进程与减进程同时访问的情况了。

StringBuffer和StringBuilder的区别
StringBuffer的方法都是有synchronized修饰的,StringBuffer就叫做线程安全的类

而StringBuilder就不是线程安全的类

4.常见的线程安全的类

    HashMap和HashTable:

     区别1: 
HashMap可以存放 null
Hashtable不能存放null
     区别2:
HashMap不是线程安全的类
Hashtable是线程安全的类

    StringBuffer 是线程安全的
    StringBuilder 是非线程安全的

    所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuilder会更快些,如果是多线程,就需要用StringBuffer 保证数据的安全性,因为StringBuilder不需要同步,更节省时间

    ArrayList和Vector

    ArrayList类的声明:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

    Vector类的声明:

public class Vector<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

区别在于Vector是线程安全的类,而ArrayList非线程安全的类

5.死锁

    1. 线程1 首先占有对象1,接着试图占有对象2
     2. 线程2 首先占有对象2,接着试图占有对象1
     3. 线程1 等待线程2释放对象2

     4. 与此同时,线程2等待线程1释放对象1

    此时,线程1和线程2就会无限等待下去,即出现死锁

6.线程之间的交互

    wait(),notify(),notifyAll();

    wait()方法暂停当前进程,使其他进程可以访问当前对象,notify()方法通知一个在wait的进程重新继续开始执行后面的工作

7.lock对象

Lock是一个接口,为了使用一个Lock对象,需要用到Lock lock=new ReentrantLock();

    lock.lock()方法表示当前线程占用lock对象,其他线程无法访问,与synchronized不同的是,synchronized块结束后,进程会自

动释放对对象的占用,而lock需要通过lock.unlock()手动释放,否则就会出现进程一直占用对象的情况,

    lock对象的tryLock方法可以避免死锁,

    lock.tryLock(1,TimeUnit.Seconds);意思是给进程1秒钟的时间去占用lock对象,如果未能占用即结束进程,不会出现多个进程互

相竞争资源的死锁。

    总结lock与synchronized的区别:::

        1. Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,Lock是代码层面的实现。
        2. Lock可以选择性的获取锁,如果一段时间获取不到,可以放弃。synchronized不行,会一根筋一直获取下去。 借助Lock的这个特性,就能够规避死锁,synchronized必须通过谨慎和良好的设计,才能减少死锁的发生。

        3. synchronized在发生异常和同步块结束的时候,会自动释放锁。而Lock必须手动释放, 所以如果忘记了释放锁,一样会造成死锁。

8.原子访问


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值