------- android培训、java培训、期待与您交流! ----------
多线程(下)
第四节:线程的调度
★线程的调度有两种模型
- 分时调度模型:指让所有的线程轮流活的CPU的使用权。
- 抢占式调度模型:指随机获取CPU的使用权,这个是Java虚拟机默认采用的模型。
- 在应用程序中,可以直接设置线程的优先级。优先级越高的线程获得CPU执行的机会就越大。
- 静态方法sleep(long millis)可以让当前正在执行的线程暂停一段时间,进入休眠状态。
- 当前线程调用sleep(long millis)方法后,在指定时间(参数millis)内是不会执行的。
- sleep(long millis)方法声明抛出InterruptedException异常。
- 因此在调用sleep(long millis)方法时应该声明抛出该异常或者捕获异常。
- 线程让步可以通过yield()方法实现,跟sleep()相似,都可以让正在运行的线程暂停
- 区别在yield()方法不会阻塞该线程,它只是将线程转换成就绪状态,让系统的调度器重新调度。
- 线程插队用join()方法,当在某个线程中调用其他线程的join()方法时,调用的线程将被阻塞,
- 知道被join()方法加入的线程执行完成后它才会继续运行。
第五节:线程的安全与同步
★线程安全问题其实就是由多个线程同时处理共享资源所导致的。
★解决问题思路:必须的保证用于处理共享资源的代码扎起任何时刻只能有一个线程访问。
- 代码执行原理:synchronized(lock){操作共享资源代码块}
- 上面的代码中,lock是一个锁对象,它是同步代码块的关键。
- 当线程执行到同步代码块时,首先会检查锁对象的标志位
- 默认情况下标志位为1,此时线程会执行同步代码块,
- 同时将锁对象的标志位置变为0。
- 当一个新的线程执行到这段同步代码块的时候,
- 由于锁对象的标识为0,新线程发生阻塞,等待当前线程执行完同步代码块后,
- 锁对象的标志位变为1,新线程才能进入同步代码块执行其中的代码。
- 如此循环往复。直到共享资源被处理完为止。
package cn.itbasis;
/*
* 售票系统
*/
public class Example03 {
public static void main(String[] args) {
//创建Ticket1对象
Ticket1 ticket = new Ticket1();
//创建new Thread()——并开启.start——4个线程
new Thread(ticket,"线程1").start();
new Thread(ticket,"线程2").start();
new Thread(ticket,"线程3").start();
new Thread(ticket,"线程4").start();
}
}
//定义一个Ticket1类实现Runnable接口
class Ticket1 implements Runnable{
//定义Ticket1并赋值10共享资源
private int tickets = 10;
//定义一个对象用于同步代码块的锁
Object lock = new Object();
public void run(){
while(true){
//定义同步代码块
synchronized(lock){
//sleep()要抛异常,设定睡眠为10毫秒
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
if(tickets>0){
//如果ticket1小于0,跳出循环
System.out.println(Thread.currentThread().getName()+"---卖票"+tickets--);
}else{
break;
}
}
}
}
}
- 同步方法:synchronization返回值类型 方法名([参数1,......]){}
- 死锁问题:两个程序都在等待对方的锁,这样就造成了程序的停滞,称为死锁。
第六节:多线程通信
★可以理解一种合作机制,两个线程之间协同完成工作
- 不恰当的例子:用水管浇花,管子一头进水,一头出水浇花,
- 整个水管就是一个容器,进水口跟出水口就是2个线程
★唤醒线程的方法:Object类的三个方法,任何类的对象都可以直接使用的三个方法
- void wait():使当前线程放弃同步锁进入等待,直到其他线程进入同步锁,
- 其他线程进入同步锁后调用notify()或notifyAll()方法唤醒该线程为止
- void notify():唤醒此同步锁上等待的第一个调用wait()方法的线程
- void notifyAll():唤醒此同步锁上调用wait()方法的所有线程