关于并发编程,准备从几个点切入:
1、java线程几本知识
2、juc锁
3、juc集合
4、线程池
-------------------------------------------------------------------
分割线开始。。。。
说到多线程,java中超父类Object中有wait()和notify()方法,包括Runnable接口和Thread类,当然Thread类也是实现了Runnable接口。
1、一个线程的生命周期可以分为五个部分:
新建状态:当一个线程对象被创建之后Thread thread = new Thread();
就绪状态:线程被调起,随时等待cpu切换过来运行线程 thread.start()
运行状态:当cpu切换过来,运行该线程时候
阻塞状态:可能被wait、join、synchronized了,放弃cpu的使用权,暂停运行
死亡状态:运行结束或者异常发生,线程死亡
以上五种状态可以用一张网上盗过来的图标示:
2、如何创建一个线程呢?
有两种方法:
1\实现Runnable接口(ImplementRunnable标示实现接口类)
ImplementRunnable i = new ImplementRunnable(); //new Runnbale新建对象
new Thread(i).start(); //新建线程对象,入参Runnable实现类,并调用
2\继承Thread类(ExtendThread表示即成thread的类)
Thread thread = new ExtendThread(); //新建thread子类对象
thread.start(); //调用
比较两种方法,第一种实现接口的方式,将runnable实现对象作为入参传入,如果new多个线程调用,可以共享该对象。
而第二种,继承父类的方式,new多个thread运行,是相互独立的,并且因为java不能多继承的原因,扩展起来没有实现接口好,所以一般推荐使用第一种方法。
*注:runnable接口中有一个run()方法,而我们调用一个线程的时候需要调用start()方法,当一个线程调用start()方法的时候,等线程进入运行状态后会调用run方法。如果我们直接调用实例的run方法并不会新起一个线程,而是在当前线程中简单的调用run方法而已。
3、关于sychronized关键字
当存在多个线程的时候,可以操作一个对象,而该对象并不允许多个线程同时操作,就比如有多个售票口,只剩下一张票,并不能每个售票口都售出这张票,这歌时候java提供了sychronize关键字去解决这个问题,哪个售票口先来买票者或者按照其他规则,就可以先获得锁,也就是获得售卖这张票的资格。
在java中,同步锁是建立在对象的基础上的,并且每个对象只有一个同步锁,当调用被sychorized修饰的模块时,就获得了该对象的同步锁,多线程访问同步锁时互斥的,也就是在同一时间内,只可能有一个线程能获取到对象的同步锁。比如线程a和线程b,当线程a获得对象同步锁的时候,线程b调用sychorized部分代码,并不能获取同步锁,必须等待a执行完毕后或者其他原因释放同步锁,线程b才能获取到对象的同步锁,并且执行同步内容。(如果线程b调用对象的非同步部分,是不需要活的锁的,可以直接调用)
*锁的域的概念:实例锁和全局锁
1、实例锁:作用在实例对象上,如public sychronized void getUser();当然,如果这个实例是单列模型,等同同于全局锁
2、全局锁:作用于对象上,无论实例多少对象,线程都共享该锁 对应于static修饰上