第九章 线程
9.1 定义、实例化并启动线程
考试目标4.1 使用java.lang.Thread和java.lang.Runnable编写代码,定义、实例化并启动新线程。
9.1.1 定义线程
扩展java.lang.Thread类,重写run()方法。
class MyThread extends Thread{
public void run(){
System.out.println("Important job running in MyThread");
}
}
实现java.lang.Runnable,实现run()方法。
class MyRunnable implements Runnable{
public void run(){
System.out.println("Important job running in MyRunnable");
}
}
9.1.2 实例化线程
每个执行线程都是作为Thread类的一个实例开始的。
对于扩展Thread类而定义的线程实例化方式如下:
MyThread t = new MyThread();
对于实现Runnable接口而定义的线程实例化方式如下:
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
Thread类的构造函数:
Thread()
Thread(Runnable target)
Thread(Runnable target,String name)
Thread(String name)
9.1.3 启动线程
在调用start()方法后,发生:
启动新的执行线程(具有新的调用栈)。
线程从新状态转到可运行状态(runnable state)。
当线程获得执行机会时,会运行它的目标run()方法。
Thread.currentThread()用来获取当前线程引用。
Thread.getName()用来获得线程的名字。
启动并运行多个线程:
每个线程都会启动,而且每个线程都将运行到结束。但是顺序,优先没有绝对保证。
当线程的目标run()方法结束时,该线程就完成了。死线程不能再次调用start()方法。
只要线程已经启动过,它就永远不能再次启动。
线程调度器:
可运行线程编程运行中线程的顺序是没有保证的。
java.lang.Thread类中控制(影响)线程的方法:
public static void sleep(long millis) throws InterruptedException public static void yield()
public final void join() throws InterruptedException
public final void setPriority(int newPriority)
//默认是5,值越大,优先越高 1-10
java.lang.Object类中控制(影响)线程的方法:
public final void wait() throws InterruptedException
public final void notify() //唤醒单个线程
public final void notifyAll() //唤醒所有线程
9.2 线程状态与转变
考试目标4.2 识别线程能够位于哪些状态,并确定线程能从一种状态转变成另一种状态的方式。
9.2.1 线程状态
新状态--new
可运行状态--runable
运行中状态--running
等待/阻塞/睡眠状态--waiting/blocked/sleeping
死状态--dead
9.2.2 阻止线程执行
一个线程被踢出“运行中”状态,而不是被送回“可运行”或“死”状态。
即:睡眠,等待,因为需要对象的锁而被阻塞。
9.2.3 睡眠
Thread的两个静态方法:
public static void sleep(long millis) throws InterruptedException //millis是毫秒
public static void sleep(long millis,int nanos) throws InterruptedException //nanos是纳秒
9.2.4 线程优先级和yield()
调度器在优先级上是没有保证的,主要是看它“喜欢。。还是不喜欢”,真够无奈的。
设置线程的优先级
t.setPriority(int i);
yield()方法
Thread的静态方法yield(),让当前的“运行中”线程回到“可运行”状态,让步给具有相同优先级的其他“可运行”线程,但这是没有任何保证的。
join()方法
Thread的非静态方法join()让当前线程加入到引用的线程尾部,这意味着调用方法的线程完成(死状态)之前,主线程不会变为可运行的。
public final void join() //要一直等待该线程结束 throws InterruptedException
public final void join(long millis) //millis为0表示要一直等下去 throws InterruptedException
public final void join(long millis, int nanos) throws InterruptedException
9.3 同步代码
考试目标4.3 给定一个场景,编写代码,恰当地使用对象锁定来保护静态变量或实例变量,使它们不出险并发访问问题。
9.3.1 同步和锁 synchronized
-
只能同步方法(或代码块),不能同步变量或类
-
每个对象只有一个锁。换句话说同一时间只有一个线程可以使用该对象的同步方法或代码块。
-
不必同步类中的全部方法。类可以同时具有同步方法和非同步方法。
-
一旦一个线程获得了对象的锁,就没有任何其他线程可以进入(该对象的)类中的任务同步方法。
-
如果类同事具有同步和非同步方法,则多个线程仍然能够访问该类的非同步方法。
-
如果线程进入睡眠,则它会保持已有的任何锁,不会释放他们。
-
线程可以获得多个锁,即线程可以同时获得多个对象的锁。
静态方法能否同步
可以,静态代码块也可以。例如:
public static synchronized int getCount(){
return count;
}
public static int getCount(){
//注意synchronized关键字后面括号里的内容:即要锁的类或对象
synchronized(MyClass.class){
return count;
}
}
如果线程不能获得锁会怎么样?
会阻塞,等锁释放。
何时需要同步?
书云:对于复杂的情况“如果你不想它的话,你的生命就会更长、更愉快。真的如此,我们没有撒谎。”
线程安全类
StringBuffer等
9.3.2 线程死锁
9.4 线程交互
考试目标4.4 给定一个场景,编写代码,恰当地使用wait()、notify()和notifyAll()方法。
必须在同步方法内调用wait()、notify()和notifyAll()方法!线程不能调用对象上的等待或通知方法,除非它拥有该对象的锁。
9.4.1 当多个线程等待时使用notifyAll()
在循环中使用wait()
- 大小: 38.1 KB
分享到:
相关推荐
scjp考试资料,其中包含题目,答案,ppt,模拟试题,复习笔记,常见问题
SCJP 310-065 全真模擬測驗 2009/09考過,命中率95
SCJP考题和学习笔记
大小: SCJP_Guide_考试认证指南.pdf
SCJP_经典题笔记之一,可以看之,1分而已
java scjp的官网认证资料,应该会有用吧
sjcp的考试的题目...希望对哥们你有帮助.
scjp笔记 考过scjp的学生的第一手资料 强烈推荐
Testpassport最新SUN_SCJP_310-065_题库免费下载.pdf
sun官方提供的scjp考试范围,考前必看!
对于Java程序设计员,Sun推出两项认证:Sun Certificated Java Programmer (SCJP)和Sun Certificated Java Developer(SCJD)。 SCJP 可以说各种Java认证的基础,相对于SCJD来说,SCJP跟侧重于测验您的Java程序...
蓝小刀的学习笔记_SCJP1.4.doc
本书主要内容包括:声明和访问控制、面向对象、赋值和初始化、运算符、流程控制、异常和断言、I/O、格式化和解析、泛型、集合、内部类、线程和Java开发。书中在介绍考试要点时针对每个考试目标,使用了大量的插图...
SCJP复习笔记,其中有复习SCJP过程中的一些问题供大家分享
专为sun的SCJP认证而编制,内容涉及了SCJP认证的方方面面
scjp简明教程for scjp 5,第一遍复习适用
关于sun公司提供scjp认证的有关习题以及答案 对要考scjp认证的兄弟姐妹们可能会有帮助
SCJP_6.0认证教战手册考题1-244