1、进程和多相处的概念以及线程的优点
什么是进程?百度百科给出的解释:进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行所发生的活动,是程序在一个数据集合上运行的的过程,它是系统进行资源分配和调度的一个独立单位。
什么是线程?线程可以理解成是在进程中独立运行的子任务。
使用多线程技术可以最大限度的利用cpu资源,同时运行多个任务。
多线程是异步的,代码的顺序并不是线程执行的顺序,线程被调用的时机是随机的。
2、java实现多线程的两种方式
继承Thread类和实现runnable接口。哪一种方式比较好?java采用的是单继承的机制,如果有其他类需要继承那么采用实现runnable接口的方式是比较推荐的。但是两种方式创建的线程在工作时的性质是一样的,没有本质区别。Thread类也实现了Runnable接口,Thread(Runnable target) 不光可以传入Runnable接口的对象,也可以将一个Thread对象中的run() 方法交由其他的线程进行调用。
start方法和run方法的区别:
start方法通知“线程规划器”此线程已经准备就绪,等待调用线程对象中的run方法,具有异步运行的效果。并且start方法调用的顺序并不是线程执行的顺序。
run方法,如果直接调用run方法,是同步执行的效果。
3、实例变量与线程安全
如果一个实例变量需要在多个线程共享,就需要对相关代码加锁(对象、方法或者代码块),可以通过 synchronized关键字(还有其他的方式)来实现,加锁的代码被称之为“互斥区”或“临界区”。
一个线程想要去执行同步方法里的代码时,线程首先要去尝试去拿这把锁,如果能拿到锁则执行同步代码里的方法。反之,就不断的尝试去拿这把锁,直到拿到为止。
关于线程和非线程安全的理解:如果一段代码在多线程环境下和单线程环境下执行的时候其变量和结果的值是一致的那么就称之为线程安全,反之为非线程安全。
注意i-- 和System.out.println()的异常;
4、常用的方法
1)、currentThread() 方法:
返回代码段正在被哪个线程调用的信息
2)、isAlive()
测试线程是否处于活动状态(线程已经启动且尚未终止),注意Thread.currentThread 和 this 的差异。还需要注意将线程对象做为参数传入Thread对象的情况。
3)、sleep()
在执行的毫秒内让“正在执行的线程”休眠; 正在执行 = this.curtentThread
4)、getId()
获取线程的唯一标识
5、停止线程
1)、使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
2)、使用stop强行终止,(stop,resume,suspend都是过期作废)
强行停止可能使一些清理性的工作得不到完成;
使锁定的对象解锁,导致数据得不到同步处理,出现数据不一致的问题
suspend 和resume,极易造成公共的同步对象的独占,使其他线程无法访问公共同步对象
suspend 和resume,也容易造成数据不同的情况
yield() 方法: 放弃当前的cpu资源,将他让给其他的任务,但是放弃的时间不确定。
3)、使用interrupt方法中断线程
interrupt() 方法只是打了一个停止的标记,并不是真正的停止线程。
interrupted() 测试当前线程是否中断,当前线程=运行this.interrupted方法的线程,并清除中断状态
isInterrupted() 测试线程(Thread对象)是否中断,不清除状态标志
通过,interrupt、interrupted 和异常的的组合可以实现停止线程。
在sleep中interrupte 会抛InterruptedException,并且会清除停止状态
建议使用异常方法来实现线程的停止,因为在catch块中能够使异常上抛,使线程停止的事件得以传播。
6、线程的优先级
优先级高的线程得到cpu的资源较多(获得的cpu的概率较高)
通过setPriority方法来设设置优先级(常量有:MIN_PRORITY;NORM_PRORITY;MAX_PRORITY)
优先级具有继承性
优先级具有规则性,优先级比较高的线程会比有比较大的概率获得CPU资源
优先级具有随机性,优先级高的线程不是每次都能有限获得CPU资源
7、守护线程
两种线程:用户线程和守护线程
当进程中不存在非守护线程的时候守护线程就自动销毁;守护线程的典型例子:GC