基本概念
进程:正在执行的应用程序
线程:进程的执行单元,执行路径
多进程的意义?
提高CPU的使用率
多线程的意义?
提高应用程序的使用率
start()和run()的区别
start()先启动线程,再由JVM调用run()方法
run()直接调用仅仅是普通方法
多线程的实现方案(自己补齐步骤及代码掌握)
A:继承Thread类,重写run()方法,将需要用多线程执行的代码放在run()方法中
B:实现Runnable接口,重写run()方法,将需要用多线程执行的代码放在run()方法中
启动多线程
A:继承Thread类
new 一个自定义的继承了Thread的类(run方法已重写),调用start()方法,调用一次就是启动了一个线程
B:实现Runnable接口
new 一个自定义的实现了Runnable接口的类(run方法已重写)
创建一个Thread类的对象,将自定义的实现类作为参数放在构造方法中,调用start()方法
线程类Thread的api
* 如果使用实现接口的方式则不能调用这些方法,需要先使用currentThread();获取当前线程再调用
* getName(); 获取当前线程的名字
* setName(); 设置名字
* currentThread(); 获取当前正在执行的线程对象
* getPriority(): 返回线程对象的优先级
* setPriority(int num); 设置线程优先级(范围1-10,默认为5)
* sleep(long millis); 暂停millis毫秒
* join(); 调用这个方法的线程CUP会先执行完该线程run();中的所有代码再执行其他线程的代码
* yield(); CPU暂停当前执行的线程对象并执行其他线程
* setDeamon(boolean on); 设置守护线程(被设置成守护线程则会在主线程结束后立即结束)
* stop(); 让线程停止,后面所有代码不再执行(有不安全性,不建议使用)
* interupt(); 把线程的状态停止,并抛出一个InterruptedException,catch异常后代码还可以继续执行
* getThreadGroup() 获取线程所属的线程组,默认情况下都属于main线程
线程组对象的方法
getName() 获取线程组的名字
new ThreadGroup("线程组名字") 新建线程组
new Thread(线程组名字,Runnable实现类,"线程名") 给线程指定线程组
判断一个程序是否有线程安全问题的要素
* 是否多线程环境
* 是否有共享数据
* 是否有多条语句操作共享数据
解决线程安全问题
* 同步代码块synchronized(对象){需要同步的代码块} 注:用作锁的对象需要是Runnable实现类的成员变量(这是为了保证锁是同一个)
* 同步普通方法(synchronized加在方法上权限修饰符后面),用this做锁
* 同步静态方法(synchronized加在方法上权限修饰符后面),用类是字节码文件做锁
* Lock锁(不常用)