一、线程与多线程
线程
就是可执行的代码段,
进程的最小执行单元;
线程要服务于
进程
,一个进程有好多个线程,
main方法
就是主线程,多个线程同时执行就是多线程,线程池就是把准备好的线程放到线程池里,如果处理请 求需要调用线程的时候,就从线程池里去调用,用完以后再放回到线程池里,这样就防止高 并发节省资源。
多线程
就是多个线程同时运行,
即是同时委派多个线程去处理一个或者多个任务;多个线程处理一个任务时称为并发;多个线程处理
多个任务则为并行
,多线程无非是为了提高代码的执行效率,提高客户的体验,解决高并发。
二、线程状态
线程一般具有六种状态,即
新建、正在运行、计时等待、永久等待、阻塞、终止。
①新建状态:
线程创建好
②正在运行状态
调用了 start 方法状态
③阻塞状态
加了同步锁的代码,多线程进行访问的时候,会有阻塞状态
④无限等待状态
调用了 wait 方法,无限等待了,等待 notify 或者 notifyAll 方法进行唤醒
⑤计时(限时)等待状态
自动唤醒,相当于使用了 sleep(1000) 或者 wait(传递时间);
⑥死亡(结束)
不用结束线程,执行完 run 方法里的代码后,会自动结束线程
三、同步锁(synchronized)
1、同步代码块
将业务过程使用
同步锁(synchronized)
进行修饰,对线程对象自动进行加锁,保证同一时间进入业务流程代码块中的线程对象只有一个,其他线程对象处理等候状态;
同步代码块想要能够锁住线程对象,要求线程对象是同一个对象,即所有的线程对象都要通过同一个自定义类对象创建;
2、同步方法
同步方法
分为静态的和非静态的;
静态的同步方法可以锁住任意由同一个
class
文件创建的对象;
非静态的同步方法跟同步代码块一致,只能锁同一个对象;
同步方法的声明:
synchronized
修饰方法,方法内部是业务流程代码;如果是静态的再加上
static
修饰词
3、Lock 锁
Lock 锁
需要手动进行加锁与释放锁,和同步代码块类似(锁同一个对象),只不过同步代码块是自动实现加锁和释放锁;
四、线程通信
传统的线程通信-
wait()
与
notify()
方法
notify()
和
notifyAll()
对于唤醒的操作有两个:notify()、notifyAll()。一般来说,所有等待的线程会按照顺序进行排列,如果现在使用了 notify()方法的话,则会唤醒第一个等待的线程执行,而如果使用了 notifyAll()方法,则会唤醒所有的等待线程,哪个线程的优先级高,哪个线程就有可能先执行。
五、多线程解决高并发
synchronized
关键字主要解决多线程共享数据同步问题。
ThreadLocal
主要解决多线程中数据因并发产生不一致问题。
ThreadLocal 和 Synchonized 都用于解决多线程并发访问但是 ThreadLocal 与 synchronized
有本质的区别:
synchronized 是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。
而 ThreadLocal 是为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并
不是同一个对象,这样就隔离了多个线程对数据的数据共享。而 Synchronized 却正好相反,
它用于在多个线程间通信时能够获得数据共享。
六、Java中实现多线程代码的三种方式
一种是继承
Thread 类
另一种就是实现
Runnable 接口
第三种是使用 java.util.concurrent.Executors 类里的
newFixedThreadPool(int )
创建线程池.
还有一种就是使用 Spring 框架去实现线程池了