马士兵 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. 可以有两种方式穿件新的线程:

① 第一种(推荐使用,能用接口不用继承):

⑴ 定义线程类,实现 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. 线程的状态转换:

1dac5791d695065aad805550896719d6.png

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() 方法:强制关闭线程(有try...catch...可执行)。

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 只锁定被修饰的方法内的语句(锁不住成员变量),其他方法仍可继续访问成员变量。即:只保证同一时刻只有一个线程访问被修饰的语句,不保证访问同一资源的其他方法。(解决办法:锁住所有访问同一资源的方法。前一个方法已锁定,后一个方法必须等前一方法执行完才可再锁定)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值