1.进程
进程:是正在运行的程序
- 是系统进行资源分配和调用的独立单位
- 每一个进程都有它自己的内容空间和系统资源
2.线程
线程:是进程中的单个顺序控制流,是一条执行路径
- 单线程:一个进程如果只有一条执行路径,则称为单线程程序
- 多线程:一个进程如果有多条执行路径,则称为多线程程序
多线程的实现方式一:
通过继承Thread类的方式实现多线程
- 定义一个类继承Thread类
- 在该类中重写run()方法
- 创建该类的对象
- 启动线程
public class MyThread extends Thread{
public MyThread(){}
public MyThread(String name){
super(name);
}
@Override
public void run(){
for(int i=0;i<100;i++){
System.out.println(getName()+":"+i);
}
}
}
public class MyRunnableDemo{
public static void main(String[] args){
//MyThread my1 = new MyThread();
//MyThread my2 = new MyThread();
MyThread my1 = new MyThread("线程1");
MyThread my2 = new MyThread("线程2");
my1.start();
my2.start();
}
}
线程优先级
线程有两种调度模型:
- 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
- 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取CPU时间片相对多一些
- Java使用的是抢占式调度模型
Thread 类中设置和获取线程优先级的方法:
- public final int getPriority():返回此线程的优先级
- public final void setPriority(int newPriority):更改此线程的优先级
线程优先级的常量:
- Thread.MAX_PRIORITY:最高优先级为 10
- Thread.MIN_PRIORITY:最低优先级为 1
- Thread.NORM_PRIORITY:默认优先级为 5
线程控制:
线程生命周期:
多线程的实现方式二:
通过实现Runnable接口的方式实现多线程
- 定义一个类实现Runnable接口
- 在该类中重写run()方法
- 创建该类的对象
- 创建Thread类的对象,把该类对象作为构造方法的参数
- 启动线程
public class MyRunnable implements Runnable{
@Override
public void run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class MyRunnableDemo{
public static void main(String[] args){
MyRunnable my = new MyRunnable();
//Thread t1 = new Thread(my);
//Thread t2 = new Thread(my);
Thread t1 = new Thread(my,"线程1");
Thread t2 = new Thread(my,"线程2");
t1.start();
t2.start();
}
}
多线程实现的两种方式的区别:
相比继承Thread类,实现Runnable接口的好处
- 避免了Java单继承的局限性
- 适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想
3.线程同步
(1)同步代码块
(2)同步方法
(3)线程安全的类
(4)Lock锁
Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作
Lock中提供了获取锁和释放锁的方法:
- void lock():获得锁
- void unlock():释放锁
Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
ReentrantLock的构造方法:
- ReentrantLock():创建一个ReentrantLock的实例
public class SellTicket implements Runnable{
private int tickets = 100; //票数
private Lock lock = new ReentrantLock();
@Override
public void run(){
while(true){
try{
lock.lock();
if(tickets>0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}finally{
lock.unlock();
}
}
}
}
public class SellTicketDemo{
public static void main(String[] args){
SellTicket st = new SellTicket();
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
t1.start();
t2.start();
t3.start();
}
}