华恩JAVA班第30天
---------------------------多线程--------------------------- 主要内容: 线程的基本概念 线程的创建和启动 线程的调度和优先级 线程的状态控制 线程同步 ----------------------------------- 线程是一个程序内部的顺序控制流: 线程是程序内部不同的执行路径.. 线程和进程的区别: 1.每个进程都有独立的代码好数据空间(进程上下文),进程间的 切换会有较大的开销。 2.线程可以看成是轻量级的进程,同意类线程共享代码和数据空间, 每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。 3.多进程:在操作系统中能同时运行多个任务(程序) 4.多线程:在同一应用程序中有多个顺序流同时执行 Java的线程是通过java.lang.Thread类来实现的。 VM启动时会有一个主方法(public static void main(){})所定义的线程。 可以通过创建Thread的实例来创建新的线程 每个线程多是通过某个特定的Thread对象所对应的方法run()来完成其操作的, 方法run()称为线程体 通过调用Thread类的start()方法来启动一个线程。 ------------------------------------ 线程的创建和启动: 两种方法创建线程: 1.定义线程类实现Runnable接口 Thread myThread=newThread(target) //Target为Runnable接口类型 Runnable中只有一个方法: public voidrun(); //用以定义线程运行体 使用Runnable接口可以为多个线程提供共享的数据 在实现Runnable接口的类的run方法定义中可以使用Thread的静态方法 public static ThreadcurrentThread(); //获取当前线程的引用 2.可以定义一个Thread的子类并重写其run方法,如: class MyThread extends Thread{ public void un(){……}
} 然后生成该类的对象 MyThread myThread=new MyThread(……); 能使用接口就不要从Thread继承 创建---start()--->就绪状态<----调度---->运行状态--------->终止 | ^ | | 阻塞解除 导致阻塞的事件 | | ---------->阻塞状态------------ ------------------------------------ 线程控制基本方法: isAlive(); //判断线程是否还“活”着,即线程是否还未终止 getPriority(); //获取线程的优先级数值 setPriority(); //设计线程的优先级数值 Thread.sleep(); //将当前线程睡眠指定毫秒数 join(); //调用某线程的该方法,将当前线程与该线程“合并” //该线程结束,再恢复当前线程的运行 yield(); //让出CPU,当前线程进入就绪队列等待调度 wait(); //当前线程进入对象的waitpool notify()/notifyAll(); //唤醒对象的waitpool中的一个/所有等待线程 ------------------------------------ sleep/join/yield方法 Sleep方法: 可以调用Thread的静态方法 public static void sleep(long millis) throwsInterruptedException 使得当前线程休眠(暂停停止执行millis毫秒)。 由于是静态方法,sleep可以由类名直接调用: Thread.sleep() Join方法: 合并某个线程 yield方法 让出CPU,给其他线程执行的机会 ----------------------------------- 线程的优先级别: Java提供了一个线程调度器来监控程序中启动后进入就绪状态的所有线程。
线程调度器按照线程的优先级决定应调度那个线程来执行。 线程的优先级用数字表示,范围1到10,一个线程的缺省优先级是5. Thread.MIN_PRIORITY=1; Thread.MAX_PRIORITY=10; Thread.NORM_PRIORITY=5; 使用下述方法获得或设置线程对象的优先级 int getPriority(); void setPriority(intnewPriority); ====================================================================== --------------------------线程的同步:重点---------------------------- 项目JavaStudy-->(源包)src.(包)study.Thread.(类)TestSync.java 用该关键字锁定一个函数,相当于锁定该函数内部所有的语句。 ----------------------------------- 在java中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象都 应该对应于一个可称为“互斥锁”的标记,这个标记保证在任意时刻,只能有一个 线程访问该对象。 关键词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){} ------------------------------------- 死锁的发生: 例:每个线程都需要锁定两个对象,但是属于交叉锁定状态时,都在等待被另外一个线程锁定的对象释放,导致死锁。 死锁模拟示例:JavaStudy-->src.study.Thread.TestDeadLock.java 著名死锁案例:哲学家吃饭问题:每个人都有一支筷子。 解决办法: 1,加粗锁的粒度 2.其他 ---------------------------------------------------------------------------- wait、sleep区别
---------------------------------------------------------------------------- wait、sleep区别 wait时别的线程可以访问锁定对象 调用wait方法的时候必须锁定该对象 sleep时,别的线程也不可以访问锁定对象 ---------------------------------------------------------------------------- 总结: 线程/进程的概念 创建和启动线程的方法 sleep join yield synchronized wait notify/notifyAll
多线程实例
*文件名称:ThreadDemo1.java *功能说明: *开发人员:Ziu Ginzeon *创建时间:2013年7月27日 下午4:16:49 public class ThreadDemo1 {
public static void main(String[] args) throwsInterruptedException { // TODO Auto-generated methodstub MyThread1 t = newMyThread1(); t.start(); while(true){ System.out.println("兔子领先了,别骄傲"); } }
} class MyThread1 extends Thread{ public void run(){ while(true){ System.out.println("乌龟领先了,别骄傲"); } } }