Java多线程编程核心技术:第一章总结

  1. 进程:进程是操作系统结构的基础;是一次程序的执行;是一个程序及其数据在处理机上顺序执行时所发生的活动;是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位;
  2. 线程:在进程中独立运行的子任务;
  3. 一个进程正在运行时至少会有一个线程在运行,比如主线程就是由JVM创建的;
  4. Thread类实现了Runnable接口,它们之间具有多态关系;但是使用Thread类创建多线程时,最大的局限就是不支持多继承,由于Java的单继承局限,所以为了支持多继承,完全可以实现Runnable接口的方式,一遍实现按,一遍继承;这两种方式创建的线程在工作的时候是没有本质的区别的
  5. 使用多线程技术时,代码的运行结果与代码的执行顺序或调用顺序是无关的;
  6. Thread类创建的线程调用start方法来启动,此方法通知“线程规划器”来调用线程对象的run方法;交给系统来安排时间调用run方法,具有异步执行的效果;如果直接调用Thread对象的run方法,就不是异步执行了,此时并不交给线程规划器来处理,而是同步;
  7. sunchronized可以在任意对象及方法上加锁,加锁的这段代码称为“互斥区”或”临界区“;
  8. 非线程安全:主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程;可以使用synchronized来解决;
  9. currentThread()方法:返回代码段正在被哪个线程调用的信息;这里区别一下:MyThread类对象类构造方法的是main线程调用,而run方法是当前线程,也就是子线程调用的;
  10. isAlive ():判断当前线程是否处于活动状态;
  11. 活动状态:就是线程已经启动尚未终止,线程处于正在运行或准备开始运行的状态,就认为线程是存活的;
  12. getId() :取得线程的唯一标识:
  13. 停止线程:
三种方法:

1,使用退出标志,使线程正常退出,也就是当run方法完成后线程终止;
2,stop方法强行终止,不推荐,
3,使用interrupt方法中断线程;

13.1、interruptted()/isInterrupted两个方法的区别:

1,interrupted():测试当前线程是否已经是中断状态,执行后会将状态标志清除;第二次调用会返回false;
2,isInterrupted():测试线程Thread对象是否已经是中断状态,但不清除状态标志:
3,注意两者的调用对象,前者由Thread类调用,后者由Thread.currentThread类对象调用;
举个例子:
可是调用interrupt方法并没有停止线程,仅仅是在当前线程中打了一个停止的标记,并不是真正的停止线程;
在这里插入图片描述

13.2、能停止的线程—异常法

加入try…catch语句,注意,MyThread线程中睡眠要比主线程睡得长,不然观察不到线程停止;
在这里插入图片描述
在这里插入图片描述

14.3、注意在睡眠中停止,当子线程睡眠时间比主线程睡得时间长得话,才会进入catch语句,

运行结果注意执行顺序即可;如果主线程一开始就调用interrupt不睡眠的话,子线程会先执行完睡眠前的语句,然后直接进入catch语句,不会执行子线程睡眠后得语句;

  1. 暴力停止法:stop停止;
  2. 方法stop()与java.lang.ThreadDeath异常,最前面有总结;
  3. 使用return也可以停止线程:
    举个栗子:此时并没有输出return后的语句;
    在这里插入图片描述
  4. 暂停线程:suspend/resume(暂停线程意味着还可以恢复)
    缺点1:容易造成公共的同步对象的独占,使得其他线程无法访问公共同步对象;
    缺点2:会导致出现值不同步的情况;对比stop;
  5. suspend与println之间的问题:这样运行程序的话不会输出main end,因为当程序运行到println方法内部停止时,同步锁未被释放,这导致当前PrintStream对象的println方法一直暂停状态,所以main方法中的输出语句迟迟不能打印;
package Day05.Test;
//suspend方法与println之间存在的问题;
class MyThread10 implements Runnable{
    private long i = 0;
    @Override
    public void run() {
        while(true){
            i++;
            System.out.println(i);
        }
    }
}
public class Test10 {
    public static void main(String[] args) throws InterruptedException {
        MyThread10 m10 = new MyThread10();
        Thread t1 = new Thread(m10);
        t1.start();
        Thread.sleep(500);
        t1.suspend();
        System.out.println("main end");
    }
}
  1. yield()方法:线程让步,放弃当前的CPU资源,将它让给其他的任务区占用CPU执行时间,但放弃的时间不确定,又可能刚刚放弃,马上又获得CPU时间片;
  2. 线程的优先级:操作系统中优先级较高的线程的到的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务;设置线程优先级有助于帮“线程规划器”确定在下一次选择哪一个线程来优先执行;此处有个异常:

优先级的设置只有1–10,超出这个范围会抛出异常;throw new IllegalArgumentException();

Java中有三个常量来预置定义优先级的值:
MIN_PRIORITY = 1;
NORM_PRIORITY = 5;
MAX_PRIORITY = 10;

线程优先级具有继承性,比如在A线程中启动B线程,那么B线程的优先级跟A线程的优先级是一样的;

  1. 注意:高优先级的线程总是大部分先执行完,并不是全部优先执行完,这点要注意,线程的优先级具有一定的规则性,也就是CPU尽量将执行资源让给优先级比较高的线程,并不是必须让给;优先级具有随机性,也就是优先级高的线程不一定每次都先执行完;线程优先级跟打印顺序无关,他们的关系具有不确定性和随机性;
  2. 优先级高的比优先级低的运行速度快一点;
  3. 守护线程与用户线程

守护线程:典型的就是垃圾回收线程,当进程中不存在非守护线程时,守护线程自动销毁;
*
方法setDaemon,设置当前线程为守护线程;

第一章出现的几个异常
1. i–与System.out.println()的异常:

注意,i–与System.out.println的异常;本次测试的目的是虽然println方法在内部是同步的,但i–的操作却是在进入println之前发生的,所以有发生非线程安全问题的概率,如图,出现了两次i=5;还是需要给run方法加上synchronized方法;
在这里插入图片描述
println内部代码:

  public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
2.方法stop()与java.lang.ThreadDeath异常

调用stop()方法时会抛出此异常,单通常不需要显式的捕捉;
在这里插入图片描述
如图:如果强制使线程停止则有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现了数据不一致的问题;

下面看一下释放锁导致数据不一致的结果:如果出现这种情况,程序处理的数据就有可能遭到破坏,最终导致程序执行的流程错误;age赋值完后,id来不及赋值;
在这里插入图片描述
在这里插入图片描述

3.设置优先级时出现的异常

设置优先级超出1–10这个范围后抛出异常
Exception in thread “main” java.lang.IllegalArgumentException
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值