java多线程

多线程相关知识(浅)

1.三种方法创建线程

  • 继承thread类
  • 实现接口runnable
  • 实现callable接口

2.三种方法的区别

  • thread是个类只能继承一个,不推荐用
  • runnable是个接口,一个类可以实现多个接口,推荐使用
  • callable与runnable最大的区别在于它有返回值,runnable没有

3.实现同步的几种方式

  • 基于jvm的同步机制
    1.使用synchronized(可用于修饰于方法上,也可以单独用于代码块)
    当线程想进入锁住的方法或代码块时,都需要获得该对象的锁,否则进入阻塞,每个对象只有一个锁,当运行完锁住的代码时,释放锁。
    2.用voliate修饰变量
    不同的线程修改变量,一般都是从内存中读取,复制一个模板,然后修改模板,经过一系列操作,最后再写到内存里。(这就会产生不同步的现象)。
    凡是voliate修饰的变量,每次读取都是从共享内存中读取,每次修改变量的值,都会写到共享内存中(通俗的讲就是每次读到的都是最新的,每次修改都会第一时间更新数据)
    3.wait,notify,notifyall和LockSupport里的park和unpark
    wait,notify,notifyall必须用于synchronized加锁了的方法和代码里。他们都是object类的方法。wait会使当前线程进入阻塞,并释放该对象的锁,让其他线程获取锁对象,notify会唤醒监视在这个锁对象的随机一个线程,notifyall唤醒全部。这比LockSupport差了一些。
    LockSupport里的park和unpark,是一种许可机制,park同样会使
    线程阻塞,但park和unpark不一定要写在synchronized里面,unpark可以写在park前面,当遇到park阻塞立即放行,无论在park前面调用了多少次unpark,只能起效一次(比如前面用了3次unpark,后面代码执行到park,直接放行,然后又遇到park了,它就进入阻塞了)
    4.sleep(睡眠时间),join方法
    sleep()是thread内置的一个方法,里面的参数睡眠时间,单位毫秒,它会使线程进入阻塞,停在那等待一段时间再继续,就是偷懒睡了一会,它不会释放锁,其他线程都不能获得该对象的锁。
    join也是thread的一个内置方法,当某个线程调用join()方法时,会江那个线程加入到当前线程,并等待它执行完,再继续执行当前线程。
  • 基于jdk的同步机制
    上面讲的是基于jvm的同步机制,一般要实现简单的同步用这个问题不大,但如果要用于复杂的同步,推荐使用java自己的ReentranntLock,jdk的锁比较灵活,可以自己设定是否是公平锁(公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。synchronized 中的锁是非公平的,ReentrantLock 默认情况下也是非公平的,但是也可以是公平的)。
    1.lock和unlock
    它需要自己手动加锁和手动释放锁。
    2.signal,signalAll,await效果和使用基本等同于notify,notifyAll,wait(我感觉- -)
    3.障碍器CyclicBarrier
    障碍器我理解为调节线程之间的执行顺序。
 CyclicBarrier cb = new CyclicBarrier(3,new MainTask());
                new MyThread("A", cb).start();
                new MyThread("B", cb).start();
                new MyThread("C", cb).start();
                //参数3就是有几个线程障碍,
               // MyThread里面调用await方法的时候,
               //告诉障碍器这个线程障碍已经完成了
               //当这个三个障碍都解决了,则优先执行new MainTask()
              

4.线程池
好像有好几种线程池,有缓存池,单线程池,定长线程池等等,它们都是对ThreadPoolExcutor的实现,就是把里面的参数设定好了。不推荐直接使用这些定义好的,因为它们很多情况不符合实际,占用的内存太多。并且阿里的开发手册也强制规定不能用Excutors去创建(就是不能用现成的)。

new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue workQueue,RejectedExecutionHandler handler) 
(1)corePoolSize: 核心线程(它们不会因超出空闲时间而被移除)
(2)maximumPoolSize: 线程池维护线程的最大数量 
(3)keepAliveTime: 线程池维护线程所允许的空闲时间 
(4)unit: 线程池维护线程所允许的空闲时间的单位 
(5)workQueue: 线程池所使用的缓冲队列 
(6)handler: 线程池对拒绝任务的处理策略

拒绝策略:就是就连缓冲队列里面的都装满了,还要加线程,只能拒绝了。

ThreadPoolExecutor.AbortPolicy:丢弃任务抛异常
ThreadPoolExecutor.DiscardPolicy:丢弃任务不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值