What is the thread Java语言的一个重要特性是支持多线程的程 序设计,多线程是实现并发的一种有效手段 线程是一个能独立执行自身指令的控制流 个程序中可以同时运行多个相对独立的线 程,这样的程序称为多线程程序 操作系统将CPU的执行划分为非常小的时间 片,根据一定的规则在不同的线程之间切换 使每个线程都得到执行的机会
What is the thread? • Java语言的一个重要特性是支持多线程的程 序设计,多线程是实现并发的一种有效手段 • 线程是一个能独立执行自身指令的控制流 • 一个程序中可以同时运行多个相对独立的线 程,这样的程序称为多线程程序 • 操作系统将CPU的执行划分为非常小的时间 片,根据一定的规则在不同的线程之间切换, 使每个线程都得到执行的机会
Progresses and Threads 进程与线程是两个不同的概念 ●进程是一个程序的执行序列,由操作系统调 度,是资源分配的基本单位;线程是一个进 程中的一个子序列,一般由程序负责管理 是执行的基本单位 线程共用相同的地址空间,线程之间的通信 是非常方便的,它们共同构成一个进程;进 程之间却有不同的地址空间
Progresses and Threads • 进程与线程是两个不同的概念 • 进程是一个程序的执行序列,由操作系统调 度,是资源分配的基本单位;线程是一个进 程中的一个子序列,一般由程序负责管理, 是执行的基本单位 • 线程共用相同的地址空间,线程之间的通信 是非常方便的,它们共同构成一个进程;进 程之间却有不同的地址空间
Creating Threads °类java.lang. Thread的实例表示线程对象 接口 java. lang Runnable的实现类实例表示 个可作为线程运行的对象 创建一个线程可以采用两种方式: (1)创建 Threat类的子类 (2)实现接口 java. lang Runnable
Creating Threads • 类 java.lang.Thread 的实例表示线程对象 • 接口 java.lang.Runnable 的实现类实例表示 一个可作为线程运行的对象 • 创建一个线程可以采用两种方式: (1) 创建Thread类的子类 (2) 实现接口 java.lang.Runnable
Class java, lang Thread d米右以下形式的构诰函数 class MyThread extends Thread public void run(t System. out. println(“ executing as a thread”) Ircauuaule taget, bulg ane Thread th=new My Thread; punc volubly Thread类的子类需覆盖rumn(方法
Class java.lang.Thread • Thread类有以下形式的构造函数: Thread() Thread(String name) Thread(Runnable target) Thread(Runnable target, String name) • Thread类中线程的主要功能方法是: public void run() {} • Thread类的子类需覆盖run()方法 class MyThread extends Thread{ public void run(){ System.out.println(“executing as a thread”); } } Thread th=new MyThread();
Interface java, lang Runnable class MyRunner implements Runnable( public void runt System. out. println(“ executing as a thread”); MyRunner runner=new MyRunnero; 实现 Thread th=new Thread(runner); Runnable接口的实现类对象必须转换为 hread 类的对象才能以线程的方式被运行
Interface java.lang.Runnable • Runnable接口中声明了唯一的方法 public interface Runnable{ public void run(); } • Runnable接口的实现类负责run()方法的实现, 提供作为线程运行时的功能 • Runnable接口的实现类对象必须转换为Thread 类的对象才能以线程的方式被运行 class MyRunner implements Runnable{ public void run(){ System.out.println(“executing as a thread”); } } MyRunner runner=new MyRunner(); Thread th=new Thread(runner);
runo and start Methods Thread类和 Runnable接口的rumn0方法是 个回调 Callback)方法,当 Thread类实例表 示的线程被执行时,此方法将被JM调用 完成线程的功能 Thread类的sart0方法用于启动一个线程, 使线程进入就绪状态,等待线程调度器的执 Thread th=new MyThread o; th. start0;←启动线程
run() and start() Methods • Thread类和Runnable接口的run()方法是一 个回调(Callback)方法,当Thread类实例表 示的线程被执行时,此方法将被JVM调用, 完成线程的功能 • Thread类的start()方法用于启动一个线程, 使线程进入就绪状态,等待线程调度器的执 行Thread th=new MyThread(); th.start(); 启动线程
Corrupting Data Probler T1 T2 100 a=X: b=X 象染称 a=a+200; b=b-100 X=a 300 X=b 0
Corrupting Data Problem • 当多个线程交替访问并修改同一个数据对象 时,可能会破坏数据的一致性,或称为污染 (corrupt)数据 • 共多个线程同时访问并修改的数据对象也称 为临界区域(critical regions) T1 X T2 100 300 0 X=a; a=X; b=X; a=a+200; b=b-100; X=b;
获得X上的锁 100 a=X 等待X上的锁 a=a+200 X=a; 300 释放X上的锁 获得X上的锁 b=X b=x: 生 b=b-100; Xb 200 释放X上的锁
Synchronization • 通过同步(synchronizing)对临界区域的访问 可以解决数据污染问题 • 同步锁协议:线程在操作某个对象前,必须 获得该对象上的锁(lock),完成操作后释放 对象上的锁,没有得到锁的线程必须等待锁 的释放,如果线程在操作对象的过程中发生 了异常,则自动释放对象上的锁 T1 X T2 100 300 200 X=a; a=X; a=a+200; 获得X上的锁 释放X上的锁 释放X上的锁 获得X上的锁 b=X; b=b-100; X=b; b=X; 等待X上的锁
Synchronization 在Java语言中,通过被关键字 synchronized修 饰的方法或 synchronized语句块实现对代码 的同步 包含在 synchronized方法或语句块中的代码 称为被同步的代码( Synchronized code) 当线程访问被同步的代码时,必须首先竞争 代码所属的类的对象上的锁,否则线程将等 待(阻塞),直到锁被释放
Synchronization • 在Java语言中,通过被关键字synchronized修 饰的方法或synchronized语句块实现对代码 的同步 • 包含在synchronized方法或语句块中的代码 称为被同步的代码(Synchronized Code) • 当线程访问被同步的代码时,必须首先竞争 代码所属的类的对象上的锁,否则线程将等 待(阻塞),直到锁被释放
S public class BankAccounti private long number; private long balance; public BankAccount(long initialDeposit) balance=initialDeposit 象 。当 public synchronized long getBalanceO0 程 return balance, 对 象线 public synchronized void deposit(long amount) balance+=amount
Synchronized Methods • 当关键字synchronized修饰非静态方法时,线 程访问方法获取的锁是方法所属的类的对象 上的锁,即引用this • 当关键字synchronized修饰静态方法时,线程 访问方法获取的锁是方法所属的类的Class对 象上的锁,即类的静态域类名.class • 线程在被同步的方法中调用同一对象或类上 的其它被同步的方法无需再获取锁 public class BankAccount{ private long number; private long balance; public BankAccount(long initialDeposit){ balance=initialDeposit; } public synchronized long getBalance(){ return balance; } public synchronized void deposit(long amount){ balance+=amount; } …… }