Java多线程编程核心技术-----第一章读书笔记
1.1
进程:正在执行的程序。进程是OS分配资源的最小单位。
线程:正在执行的程序的子任务。线程是程序执行的最小单位。
原:使用多线程的优点:可在同一时间运行更多不同的任务。 P3
原:使用多线程也就是在使用异步。P3(异步:你弄你的,我弄我的,互不干扰)
同步是什么?同步的概念就是共享,共享同一个资源就会出现线程安全问题,所以要加锁。
异步是什么?异步的概念就是独立,异步可以理解为多个线程之间不会竞争共享资源,当然就不会发生线程安全问题。
1.2
如何使用多线程
继承Thread类,重写run方法,调用此线程对象的start方法
实现Runnable接口,实现run方法,创建接口实现,作为Thread类对象的构造函数的参数,调用Thread对象的start方法
另外,Thread类实现了Runnable接口,因此可以把一个Thread对象转递到另外一个Thread类的构造函数中
原:thread.start()方法通知“线程规划器”,此线程已经准备就绪,等待被调用。P6
调用start()方法后,线程是可执行状态。
原:调用start()方法的顺序不代表线程启动的顺序。P7
线程的启动是随机的。
线程不安全的原因:多个线程操作了同一个变量,并且操作这个变量的语句是 非原子性操作。
原子性操作是指:只有一步的操作。 比如 i++,先读取i的值,再修改i的值自增,最后将i的值写入内存,出现了“读-改-写”的操作,出现了三次操作。
1.3
Thread.currentThread()方法返回正在被哪个线程调用的信息。
哪个线程启动后执行了此代码,返回的就是这个线程。
1.4
isAlive(),线程执行完毕为false,没有执行完毕为true。
1.5
Thread.sleep()方法让 启动线程 休眠。
让线程休眠,同时对线程的中断状态位进行监控,如果中断位一旦被置为true,那么则立即进入异常处理语句或者是抛出异常。
从interrupted()静态方法就可以知道,操作的肯定是通过静态方法返回的线程。只有currentThread()方法是静态方法,所以操作的是 当前线程。P25
不管是哪个线程直接调用了interrupt()方法,哪个线程的中断状态标志位立即被设置为true。
Thread.interrupted() 测试的是 启动 此代码的当前线程的状态标志位,获取了以后,将标志位设置为false(未 )。原因是,JVM认为你既然知道了当前线程已经被中断,那么就会有相应的处理,有了处理就解决了问题,那么现在就是没有问题了的,现在的状态为非中断状态,所以标志位设置为false。
this.isInterrupted()判断的是 直接调用此方法的线程的中断标志位,开启的线程自然是“不是中断的”,所以默认是false
在被调用interrupt()方法后,状态为就是true了。
1.7.1
哪个线程直接调用了interrupt()方法,哪个线程的中断状态位立即被设置为true。
1.7.2
当前线程:启动此代码块的线程,代表的是currentThread()返回的线程。
调用线程: 调用此方法的线程,比如this.isInterrupted()的this代表的线程。
1.7.3
通过判断调用线程的标志位,来控制调用线程它的执行任务的时间
通过抛出异常,可以直接跳入异常处理语句,避免执行后面的语句。
优劣代码对比
这种写法的优势在于:将主体部分作为核心代码,并在最前面排除执行不了核心代码的少数情况
1.7.4
如果当前线程在沉睡期间,当前线程的状态位一旦被置为true,那么将会直接进入异常处理。并且将启动线程的状态标志置为false,因为启动线程被认为已经进行了异常处理,中断状态位可以认为是未被中断(false)。
原:如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值。P31
1.7.5 - 1.7.7
执行stop()方法,强制停止了某个线程,可能导致某些重要的释放资源代码没有执行。
而使用interrupt等方法进行中断,线程一般会进入异常处理语句,对共享数据进行回滚操作或者是对资源进行释放。
另外,如果操作共享变量的语句是非原子性操作,通常会加锁。stop()方法会让线程释放同步锁。
可能会出现非原子性操作没有执行完毕就释放了同步锁,这样共享数据就出现了问题。
1.8
调用线程的suspend方法,线程暂停,但是并不释放同步锁。
sout 本身就是加锁的,如果在打印期间调用的suspend方法,那么其它线程将无法调用System.out.println()方法
可能会出现因为线程暂停而导致的数据不同步的情况
为什么不推荐使用stop()方法:因为一旦调用stop()方法,那么立即释放同步锁,很容易造成共享变量被操作到一半就停止了,然后其它线程访问了此残缺的共享变量,从而造成线程安全问题。另外,可以会导致关键资源没有被释放。
suspend方法极其容器造成死锁,因为它不释放同步锁,其它线程在唤醒它之前若要同步锁,却有获取不到,那么就出现死锁了。
1.9 线程让步
静态方法
Thread.yield()方法,相当于一个不固定时间的sleep(),所以不释放同步锁。
1.10.1
A线程启动了B线程,那么B线程的优先级继承了A线程,所以B线程的优先级与A线程相同。
10.10.2
CPU尽量把资源让给优先级较高的线程。
10.10.3
优先级高的线程不一定每次都先执行完任务。
1.11守护线程
如果程序中没有非守护线程了,那么守护线程就自动销毁了。典型的守护线程就是垃圾回收线程。
守护线程的作用是对其它线程提供服务。
---------------------------------------------------------------------------
总结:
线程暂停sleep(),线程停止interrupt相关。