多线程学习笔记(一)基本概念和方法

1实现多线程的两种方式

(1)继承Thread类,重写run方法

(2)实现Runnable接口,重写run方法

Thread类也实现了Runnable接口 。这就意味着构造函数Thread(Runnable target)不光可以传入Runnable接口的对象,还可以传入一个Thread类的对象,这样做完全可以将一个Thread对象中的run()方法交由其他线程进行调用。

2线程调用

(1)多线程的代码执行順序与调用順序无关,执行start()方法的順序不代表线程启动的順序

(2)Thread的start()方法通知“线程规划器”此线程已经准备就绪,等待调用线程对象的run()方法。具有异步执行的效果,

如果调用代码thread.run()就还是同步执行。

3多线程间的变量共享

(1)静态变量和实例变量可能多个线程共享

类变量:用static修饰

实例变量:没有static修饰的成员变量,是全局变量,包括基本数据类型和对象,保存在堆中。

局部变量:方法中的变量。每个线程有自己独立的存储空间,无法共享。

根据JMM的设计,系统存在一个主内存(Main Memory),Java中所有实例变量都储存在主存中,对于所有线程都是共享的。
每条线程都有自己的工作内存(Working Memory),工作内存由缓存和堆栈两部分组成,缓存中保存的是主存中变量的拷贝,
缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;
堆栈中保存的是线程的局部变量,线程之间无法相互直接访问堆栈中的变量。

小结:实例变量存放在堆中,保存在系统的主内存中,每个线程拷贝到自己的缓存中,1可以共享。2缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;

局部变量存放在线程的栈中,线程之间无法相互直接访问堆栈中的变量。

非线程安全:多个线程对同一对象中的实例变量进行并发访问,出现脏读(取到的数据时被修改过的)。

非线程安全存在于实例变量中,如果是方法内部的私有变量,则不存在非线程安全问题。

线程共享示例:

多线程学习笔记(一)基本概念和方法

多线程学习笔记(一)基本概念和方法

这种情况,每个线程都有自己的实例对象,此时变量不共享。

多线程学习笔记(一)基本概念和方法

这种情况,多个线程共享一个实例, 共享该实例的实例变量。

这时需要对多个线程之间进行同步。可以通过synchronized关键字实现。synchronized关键字可以在任意对象和方法上加锁,加锁的这段代码称“互斥区”和“临界区”。

4多线程几个基础方法

(1)currentThread()方法:返回代码段正在被哪个线程调用的信息。

this则指所在的线程。

例如:

多线程学习笔记(一)基本概念和方法

多线程学习笔记(一)基本概念和方法

(2)isAlive()方法:判断线程是否处于活动状态(已经启动且尚未终止)

(3)sleep()方法:让当前“正在执行的线程”休眠(暂停执行)指定毫秒数。这个正在执行的线程是指this.currentThread()返回的线程。相当于(Thread.currentThread())。

(4)getId()方法:取得线程的唯一标识。

5停止线程

(1)使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

(2)使用stop方法强行终止。会抛出java.lang.ThreadDeath异常,不建议使用。

因为:如果强制停止线程可能使一些清理性工作得不到完成。

对锁定的对象进行了“解锁”,导致数据得不到同步处理,出现数据不一致的问题。

(3)判断线程是否是停止状态

interrupted:测试当前线程是否已经中断,当前线程指运行interrupted方法的线程(不是调interrupted方法的那个线程,是interrupt在哪个线程里面运行就是哪个线程)。执行后具有将状态标志清除为false的功能

isInterrupted:测试线程Thread对象(调用isInterrupted方法的线程)是否已中断,不清除状态标志。

(4)interrupt,interrupted判断结合主动抛异常

(5)interrupt结合sleep

如果在sleep()状态下,interrupt某一线程会自动抛异常,并清除停止状态值,使之变为false

如果先interrupt某一线程,遇到了sleep方法,也会自动抛异常。停止线程。

(6)interrupt,interrupted判断结合return

不过还是建议使用抛异常法,使用异常流能更好地控制程序的运行流程,不至于代码中出现很多个return;造成污染

6suspend()与resume()

7yield()

放弃当前cpu资源,将其让给其他的任务去占用cpu执行时间。放弃时间不确定。

8线程优先级

(1)1-10级

setPriority()方法设置

(2)线程优先级具有继承性

比如a线程启动b线程,则b线程的优先级与a是一样的。

9守护线程

当进程中不存在非守护线程了,则守护线程自动销毁。典型的是GC

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2