进程
正在运行的一个程序
线程
在一个进程中,执行一套功能流程,称为线程
在一个进程中,执行多套功能流程,称为多线程
为什么使用多线程
抢占式策略系统:系统会为每个执行任务的线程分配一个很小的时间段,当该时间段使用完后,系统会强制的夺其cpu执行权交给其他线程完成任务
①可以提高效率
②增强用户体验
创建执行线程的方式
①声明一个类继承Thread类
②重写Thread类的run()方法,同时编写线程执行体
③创建该子类的实例
④通过start()启动线程,默认run()方法
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
//当前电脑cpu数量
int cpuNums = runtime.availableProcessors();
System.out.println(cpuNums);
}
public class ThreadTest01 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.start();//最终会执行cat的run()方法
}
}
class Cat extends Thread{
int count=0;
//重写run方法
@Override
public void run() {
while (true) {
//该线程每间隔一秒,输出一次
System.out.println("yhf 天下第一"+(++count)+"线程名"+Thread.currentThread().getName());
//让线程休眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count==80){
break;//=80退出
}
}
}
}
通过实现接口Runnable来开发线程
public static void main(String[] args) {
Dog dog = new Dog();
//dog.start();这里不能调用start
Thread thread = new Thread(dog);
thread.start();
}
}
class Dog implements Runnable{
}
继承Thread和实现Runnable的区别
①通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,底层都是start()->start0()
②实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制
模拟售票
方式一(超卖)
public static void main(String[] args) {
/*模拟三个窗口*/
SellTicket01 s1 = new SellTicket01();
SellTicket01 s2 = new SellTicket01();
SellTicket01 s3 = new SellTicket01();
s1.start();
s2.start();
s3.start();
}
}
class SellTicket01 extends Thread{
private static int TicketNum=100;//三个线程共享
@Override
public void run() {
while (true){
if (TicketNum<0){
System.out.println("售票结束");
break;
}
try {
//休眠50毫秒
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()
+"售出一张票"+"剩余票数"+(--TicketNum));
}
}
}
方式二(超卖)
public static void main(String[] args) {
SellTicket02 s1 = new SellTicket02();
SellTicket02 s2 = new SellTicket02();
SellTicket02 s3 = new SellTicket02();
new Thread(s1).start();
new Thread(s2).start();
new Thread(s3).start();
}
}
class SellTicket02 implements Runnable{
private static int TicketNum=100;//三个线程共享
@Override
public void run() {
while (true){
if (TicketNum<0){
System.out.println("售票结束");
break;
}
try {
//休眠50毫秒
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()
+"售出一张票"+"剩余票数"+(--TicketNum));
}
}
}
线程终止
设置一个控制变量,通过set方法修改值
线程常用方法
线程插队
守护线程和用户线程
①用户线程,也叫工作线程
②守护线程:一般是为工作线程服务的,当所有用户线程结束时,守护线程自动结束
③常见的守护线程:垃圾回收机制
线程的状态
同步机制Synchronized
不允许多个线程同时访问一个数据
互斥锁
死锁
多个线程都占用了对方的锁资源,但不肯相让,导致死锁