马⼠兵java线程_学习笔记-马⼠兵java-多线程机制
1. 线程的基本概念
a. 线程:是⼀个程序内部的顺序控制流(⼀个程序的不同执⾏路径)。(class⽂件,exe⽂件--进程--静态概念)
b. 线程和进程的区别:
① 每个进程都有独⽴的代码和数据空间(进程上下⽂),进程间的切换会有较⼤的开销。
② 线程可以看成是轻量级的进程,同⼀类线程共享代码和数据空间,每个线程有独⽴的运⾏栈和程序计数器(PC),线程切换的开销⼩。
③ 多进程:在操作系统中能同时运⾏多个任务(程序)。
④ 多线程:在同⼀应⽤程序中有多个顺序流同时执⾏。
c. Java 的线程是通过 java.lang.Thread 类来实现的。
d. 主线程:VM(虚拟机) 启动时会有⼀个由主⽅法(public static void main(){})所定义的线程。
e. 可以通过穿件 Thread 的实例来创建新的线程。
f. 每个线程都是通过某个特定 Thread 对象所对应的⽅法 run() 来完成其操作的,⽅法 run() 称为线程体。
g. 通过调⽤ Thead 类的 start() ⽅法来启动⼀个线程(若调⽤ run⽅法,则还在主线程中,执⾏完 run⽅法,才继续回到主线程)。
2. 线程的创建和启动
a. 可以有两种⽅式穿件新的线程:
① 第⼀种(推荐使⽤,能⽤接⼝不⽤继承):学习java的学习方法
⑴ 定义线程类,实现 Runnable 接⼝。
⑵ Thread myThread = new Thead(target) // target 为 Runnable 接⼝类型。
⑶ Runnable 中只有⼀个⽅法:
public void run(); // ⽤以定义线程运⾏体
⑷ 使⽤ Runnable 接⼝可以为多个线程提供共享数据。
⑸ 在实现 Runnable 接⼝的类的 run ⽅法定义中可以使⽤ Thread 的静态⽅法:
public static Thread currentThread() // 获取当前线程的引⽤
② 第⼆种(Thread 类本⾝也实现了 Runnable 接⼝):
⑴ 可以定义⼀个 Thread 的⼦类,并重写其 run ⽅法。如:
class MyThread extends Thead{
public void run() {...}
}
⑵ 然后⽣成该类的对象:
MyThread myThread = new MyThread(...)
3. 线程的调度和优先级
a. 线程的状态转换:
b. 线程控制基本⽅法:
⑴ isAlive() // 判断线程是否还“活”着,即线程是否还未终⽌。
⑵ getPriority() // 获得线程的优先级数值。
⑶ setPriority() // 设置线程的优先级数值。
⑷ Thread.sleep() // 当前线程睡眠指定毫秒数。
⑸ join() // 将当前线程与该线程“合并”,即等待该线程结束,再回复当前线程的运⾏。
⑹ yield() // 让出 CPU 当前线程进⼊就绪队列等待调度。
⑺ wait() // 当前线程进⼊对象的 wait pool。
⑻ notify() / notifyAll() // 唤醒对象的 wait pool 中的(⼀个 / 所有)等待的线程。
4. 线程的状态控制
a. sleep⽅法:
① 可以调⽤ Thread 的静态⽅法:
public static void sleep(long millis) throws InterruptedException //使得当前线程休眠(暂时停⽌执⾏ millis 毫秒,1000毫秒=1秒)
② 由于是静态⽅法,sleep 可以由类名直接调⽤:
Thread.sleep(...)
b. join⽅法:合并某个线程。
c. yield⽅法:让出CPU,给其他线程执⾏的机会(本⾝还会执⾏)。
d. interrupt() ⽅法:强制关闭线程(有可执⾏)。
e. stop()⽅法:杀死线程(已废弃,直接杀死)。
f. 让线程停⽌的最好⽅法:在线程类内定义 flag ,将其改为 false 以结束 run⽅法内的 while(flag) 循环。
g. 线程的优先级(优先级越⾼,得到 CPU 时间⽚越多):
⑴ Java 提供⼀个线程调度器来监控程序中启动后进⼊就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪个线程来执⾏。
⑵ 线程的优先级⽤数字表⽰,范围从 1 到 10,⼀个线程的缺省优先级是 5.
Thread.MIN_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
⑶ 使⽤下属线程⽅法获得或设置线程对象的优先级:
① int getPriority(); // 获得优先级
② void setPriority(int newPriority); // 设置优先级
5. 线程同步
a. 互斥锁:synchronized(this){...} (也可作为⽅法的修饰符,执⾏⽅法时,当前对象被锁定)// 锁定当前对象
b. 在JAVA语⾔中,引⼊了对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应于⼀个可称为“互斥锁”的标记,这个标记保证在任⼀时刻,只能有⼀个县城访问该对象。
c. 关键字:synchronized 来与对象的互斥锁联系。当某个对象被 synchronized 修饰时,表明该对象在任⼀时刻只能由⼀个线程访问。
① synchronized 的使⽤⽅法:
synchronized(this) {
num++;
try{Thread.sleep(1);}
catch(InterruptedException e){}
System.out.println(name+",你是第“+num+"个使⽤timer的线程");
}
② synchronized 还可以放在⽅法声明中,表⽰整个王法为同步⽅法:
synchronized public void add(String name) {...}
d. 死锁:A线程锁住a对象,访问b对象;同时,B线程锁住b对象,访问a对象。==> 出现死锁(解决办法之⼀:把锁的粒度加⼤,锁住⼀个包括a,b对象的对象即可)
e. synchronized 只锁定被修饰的⽅法内的语句(锁不住成员变量),其他⽅法仍可继续访问成员变量。即:只保证同⼀时刻只有⼀个线程访问被修饰的语句,不保证访问同⼀资源的其他⽅法。(解决办法:锁住所有访问同⼀资源的⽅法。前⼀个⽅法已锁定,后⼀个⽅法必须等前⼀⽅法执⾏完才可再锁定)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论