java多线程 ppt,java多线程ppt课件

JAVA多线程 线程的基本概念 线程的创建和启动 线程的调度和优先级 线程的状态控制 线程同步 JAVA SE基础 线程的基本概念 •线程是一个程序内部的顺序控制流。 •线程和进程的区别 Ø 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换 会有较大的开销。 Ø 线程可以看成时轻量级的进程,同一类线程共享代码和数据空间, 每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。 Ø 多进程: 在操作系统中能同时运行多个任务(程序) Ø 多线程: 在同一应用程序中有多个顺序流同时执行 nJava的线程是通过java.lang.Thread类来实现的。 n VM 启动时会有一个由主方法(public static void main() {})所 定义的线程。 n 可以通过创建 Thread 的实例来创建新的线程。 n 每个线程都是通过某个特定Thread对象所对应的方法run( )来完成 其操作的,方法run( )称为线程体。 n 通过调用Thead类的start()方法来启动一个线程。 线程的创建和启动 •可以有两种方式创建新的线程。 – 第一种 • 定义线程类实现Runnable接口 • Thread myThread = new Thead(target)//target为 Runnable接口类型。 • Runnable中只有一个方法: – public void run(); 用以定义线程运行体。 • 使用Runnable接口可以为多个线程提供共享的数据。 • 在实现Runnable接口的类的run方法定义中可以使用Thread的静 态方法: – public static Thread currentThread() 获取当前线程的引 用。 – 第二种 • 可以定义一个Thread的子类并重写其run方法如: class MyThread extends Thead { public void run(){…} } • 然后生成该类的对象: MyThread myThread=new MyThead(…) •使用那种好呢? 线程状态转换 方 法功 能 isAlive()判断线程是否还“活”着,即线程是否还未终止。 getPriority()获得线程的优先级数值 setPriority()设置线程的优先级数值 Thread.sleep()将当前线程睡眠指定毫秒数 join() 调用某线程的该方法,将当前线程与该线程“合并”,即等待 该线程结束,再恢复当前线程的运行。 yield()让出CPU,当前线程进入就绪队列等待调度。 wait()当前线程进入对象的wait pool。 notify()/ notifyAll() 唤醒对象的wait pool中的一个/所有等待线程。 线程状态转换 sleep / join / yield 方法 • sleep方法 – 可以调用Thread的静态方法: public static void sleep(long millis) throws InterruptedException 使得当前线程休眠(暂时停止执行millis毫秒)。 – 由于是静态方法,sleep可以由类名直接调用: Thread.sleep(…) • join方法 – 合并某个线程 • yield方法 – 让出CPU,给其他线程执行的机会 线程模式 § 两种线程模式: § 协作式:一个线程保留对处理器的控制直到它自己决定 放弃 § 速度快、代价低 § 用户编程非常麻烦 § 抢先式。系统可以任意的从线程中夺回对CPU的控制 权,再把控制权分给其它的线程 。 § 两次切换之间的时间间隔就叫做时间片 § 效率不如协作式高 ,OS核心必须负责管理线程 § 简化编程,而且使程序更加可靠 § 多数线程的调度是抢先式的。 线程的优先级别 • Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有 线程。线程调度器按照线程的优先级决定应调度哪个线程来执行。 • 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级 是5。 –Thread.MIN_PRIORITY = 1 –Thread.MAX_PRIORITY = 10 –Thread.NORM_PRIORITY = 5 • 使用下述线方法获得或设置线程对象的优先级。 –int getPriority(); –void setPriority(int newPriority); •不同平台上的优先级 – Solaris:相同优先级的线程不能相互抢占对方的cpu时间。 – windows:可以抢占相同甚至更高优先级的线程的cpu时间 临界资源问题(1) • 两个线程A和B在同时操纵Stack类的同一个实例(堆栈),A 正在往堆栈里push一个数据,B则要从堆栈中pop一个数 据。 class Stack{ int idx=0; char[ ] data = new char[6]; public void push(char c){ data[idx] = c; idx++; } public char pop(){ idx--; return data[idx]; } } 临界资源问题(2) 1. 操作之前 data = | a | b | | | | | idx=2 2. A执行push中的第一个语句,将c推入堆栈; data = | a | b | c | | | | idx=2 3. A还未执行idx++语句,A的执行被B中断,B执行pop方 法,返回c: data = | a | b | c | | | | idx=1 4. A继续执行push的第二个语句: data = | a | b | c | | | | idx=2 最后的结果相当于c没有入栈,产生这种问题的原因在于 对共享数据访问的操作的不完整性。 线程同步 public class Test implements Runnable { Timer timer = new Timer(); public static void main(String[] args) { Test test = new Test(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.setName(“t1“); t2.setName(“t2“); t1.start(); t2.start(); } public void run(){ timer.add(Thread.currentThread().getName()); } } class Timer{ private static int num = 0; public void add(String name){ num ++; try {Thread.sleep(1);} catch (InterruptedException e) {} System.out.println(name+“, 你是第“+num+“个使用timer的线程“); } } Synchronized总结 •无论synchronized关键字加在方法上还是对象上,它取得的锁都是锁在了对 象上,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线 程的对象访问。 •每个对象只有一个锁(lock)与之相关联。 •实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避 免无谓的同步控制。 •搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程 程序。 •还有一些技巧可以让我们对共享资源的同步访问更加安全: – 定义private 的instance变量+它的 get方法,而不要定义 public/protected的instance变量。如果将变量定义为public,对象在外 界可以绕过同步方法的控制而直接取得它,并改动它。 – 如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法 仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用 后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很 危险。 这个时候就需要将get方法也加上synchronized同步,并且,只 返回这个private对象的clone()――这样,调用端得到的就是对象副本的引 用了。 线程同步 • 在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。每 个对象都对应于一个可称为“互斥锁”的标记,这个标记保证在任一时刻, 只能有一个线程访问该对象。 • 关键字synchronized 来与对象的互斥锁联系。当某个对象synchronized修 饰时,表明该对象在任一时刻只能由一个线程访问。 … … … synchronized(this){ num ++; try {Thread.sleep(1);} catch (InterruptedException e) {} System.out.println (name+“, 你是第“+num+“个使用timer的线程“); } … … … Ø synchronized 的使用方法: Ø synchronized 还可以放在方法声明中,表示整个方法为同步方法,例如: synchronized public void add(String name){…} 面试:Wait sleep区别 • 来源不同 – Sleep是Thread提供的方法 – Wait继承自Object • 代码位置不同 – Wait需要写在Synchronize语句块里面 • 是否释放锁定对象 – 调用wait方法,释放锁定该对象 – Sleep时别的线程也不可以访问锁定对象 总结 • 线程、进程的概念 • 线程的创建和启动方式 • 线程的调度和优先级 • Sleep • Join • Yield • synchronized • Wait • Notify、notifyAll Q&A Any Question? www.Coredu.cn 谢谢大家

展开阅读全文

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值