多线程

并发与并行

并发:

  • 指两个或多个事件在同一个时间段内发生

并行

  • 指两个或多个事件在统一个时刻发生

线程与进程

线程

  • 进程中的执行单元、负责当前进程中程序的执行,一个进程至少有一个线程。

进程

  • 一个进入内存的(运行)的程序,一个应用程序可以有多个进程(完成多个不同的功能)比如qq可以同时登录多个账号。

线程调度

分时调度

  • 所有线程轮流使用cpu,平均分配每个线程的cpu使用时间

抢占式调度

  • 优先级高优先调用cpu

线程创建

第一种方法

1.创建java.lang.Thread子类

2.重写run方法

3.创建子类对象

4.调用子类对象start()方法

注意:如果是调用run方法,则只是把run()方法加入到Main线程中执行,而不是在新开辟的线程中执行,调用start()会创建新的栈空间运行新线程

第二种方法

使用匿名内部类创建(Runnable())

Thread t=new Thread(new Runnable(){
   

	@overridepublic void run(){
   }

})

Thread的常用方法

获取线程名称

  • public String getName() 获取线程名称
  • public static String currentThread() 获取正在运行的线程

设置线程名称(两种方法)

  • public void setName()
  • 创建带参数的构造方法,传递参数到父类的构造方法

控制线程

  • public void sleep(long mills) 使线程休眠
  • public void notify() 激活线程

Thread 和Runnable 的区别

Runnbale

  • 避免了单继承
  • 程序解耦,实现run定于与start调用分开

线程安全

不同线程对同一资源的同时访问会出现安全问题

线程同步

同步代码块

格式

锁对象需要是相同的

synchronize(锁对象){

同步的代码块

}

锁对象相当于钥匙,同步的代码块相当于房子,线程先判断是否持有锁对象,当线程持有锁对象的时候可以运行同步代码块的代码,没有锁对象会进入阻塞对象,直到拥有锁对象的线程将锁对象归还。

同步方法

定义方法

  • public syschronize void method(){};

    同步方法的锁对象为实现类对象(即实现了runnable接口的类对象)

静态同步方法

public static syschronize void method(){}

锁对象:本类的class对象

Lock 锁

java.util.concurrent.locks (jdk1.5)

方法

  • void lock()

  • void unlock()

lock的实现类

Reentrantlock

  1. 在成员位置创建对象

  2. 在可能出现安全问题的地方调用该方法获取锁

  3. 在同步代码结束处调用unlock

Lock l=new Reentrantlock();

l.lock();//在可能出现安全问题的地方调用该方法获取锁

l.unlock();//在代码结束处调用

线程的状态

此图片来源黑马java教学视频

6种状态

新建状态

运行状态

阻塞状态(与其他线程争夺锁对象,争夺失败进入该状态)

休眠状态

无限休眠状态(调用了wait()方法,不传参)

死亡状态

线程的等待与唤醒

wait()与notify()的转化

使用锁对象调用以上的两个方法,实现线程的等待与唤醒,锁对象需要唯一

notifyall() 唤醒所有的线程

同上

线程池的代码实现

java.util.cocurrent.Excutors 用于产生线程池

方法

  1. static ExecutorService newFixedThreadPool(int Threads) 创建线程池

    返回ExecutorService 接口的实现类

java.util.cocurrent.ExcutorService 线程池操作对象

接口的方法

  1. void submit(Runnable ) 提交一个Runnable

  2. void shutdown 毁线程池对象

使用步骤

  1. 创建线程池
  2. 创建一个Runnable的实现类,重写run方法,设置线程任务
  3. 调用submit方法,传递Runnable
  4. 调用shutDowm方法,销毁线程池对象