---------------------------多线程--------------------------
主要内容:
线程的基本概念
线程的创建和启动
线程的调度和优先级
线程的状态控制
线程同步
线程是一个程序内部的顺序控制流:
线程是程序内部不同的执行路径.
线程和进程的区别:
1.每个进程都有独立的代码好数据空间(进程上下文),进程间的
切换会有较大的开销。
2.线程可以看成是轻量级的进程,同意类线程共享代码和数据空间,
每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
3.多进程:在操作系统中能同时运行多个任务(程序)
4.多线程:在同一应用程序中有多个顺序流同时执行
Java的线程是通过java.lang.Thread类来实现的。
VM启动时会有一个主方法(public static void main(){})所定义的线程。
可以通过创建Thread的实例来创建新的线程
每个线程多是通过某个特定的Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体
通过调用Thread类的start()方法来启动一个线程。
------------------------------------ ------------------------------------ ------------------------------------
线程的创建和启动:
两种方法创建线程:
1.定义线程类实现Runnable接口
Thread myThread=new Thread(target) //Target为Runnable接口类型
Runnable中只有一个方法:
public void run(); //用以定义线程运行体
使用Runnable接口可以为多个线程提供共享的数据
在实现Runnable接口的类的run方法定义中可以使用Thread的静态方法
public static Thread currentThread(); //获取当前线程的引用
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(); //当前线程进入对象的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,给其他线程执行的机会
-----------------------------------
线程的优先级别: Java提供了一个线程调度器来监控程序中启动后进入就绪状态的所有线程。
线程调度器按照线程的优先级决定应调度那个线程来执行。
线程的优先级用数字表示,范围1到10,一个线程的缺省优先级是5.
Thread.MIN_PRIORITY=1;
Thread.MAX_PRIORITY=10;
Thread.NORM_PRIORITY=5;
使用下述方法获得或设置线程对象的优先级
int getPriority();
void setPriority(int newPriority);
======================================================================
--------------------------线程的同步:重点!!!----------------------------
项目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时别的线程可以访问锁定对象
调用wait方法的时候必须锁定该对象
sleep时,别的线程也不可以访问锁定对象
----------------------------------------------------------------------------
总结:
线程/进程的概念
创建和启动线程的方法
sleep
join
yield
synchronized
wait
notify/notifyAll |