多线程
- 进程:一个正在运行的程序 就是一个进程
- 一个进程可以有一个或多个线程
- 线程:执行的任务
- 好处:提高任务的执行效率
- (线程本身也会耗费系统资源 创建线程要把握一个度)
分时调度
- CPU同一时间只能执行一个任务(CPU单核单线程)
- 现在要同时执行3个任务
- 这时CPU就会为 这3个任务开辟3个独立的执行路径(运行功能的代码)
- CPU会在这3个任务之间进行快速切换
- 抢占资源:抢夺CPU的执行资源
创建一个线程
java中使用Thread类
例:
//创建线程类的子类
class SubThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
System.out.println(“run” + i);
}
}
}
public static void main(String[] args) {
//创建子线程
SubThread subThread = new SubThread();
//开启线程
//执行任务 就是 重写run方法
//run 和 start的区别
//1.直接调用run方法 就相当于调用成员方法
//2.直接调用start 开启线程
//3.线程中执行的任务 是run方法中的代码
subThread.start();
SubThread subThread1 = new SubThread();
SubThread subThread2 = new SubThread();
subThread1.start();
subThread2.start();
for (int i = 0; i < 100; i++) {
System.out.println("main" + i);
}
}
注意:
main调用
-
1.jvm调用main函数
-
2.cpu就为main开辟一个独立的执行路径
-
3.这个路径中 就执行 main中的代码
-
程序只有一个主线程 除了主线程其他的都叫子线程
-
这个主线程名字 就叫 main
线程的名字
- 主线程:main
- 子线程:默认 Thread-X(X从0开始)
例:
class NameThread extends Thread{
//构造方法
public NameThread() {
// TODO Auto-generated constructor stub
}
//构造方法设置名字
public NameThread(String name) {
// TODO Auto-generated constructor stub
super(name);
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
// 获取线程的名字
Thread currentThread = Thread.currentThread();
System.out.println(currentThread.getName() + “–” + i);
}
}
}
public static void main(String[] args) {
NameThread t1 = new NameThread(“他”);
NameThread t2 = new NameThread(“她”);
t1.setName(“它”);
t1.start();
t2.start();
//获取当前正在执行的线程对象
//放到哪个线程当中 就表示哪个线程对象
Thread currentThread = Thread.currentThread();
System.out.println(currentThread.getName());
}
线程的第二种创建方式
class RunnableImpl implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args) {
//创建接口实现类对象
RunnableImpl runnableImpl = new RunnableImpl();
//创建线程类对象
Thread thread = new Thread(runnableImpl);
//开启线程
thread.start();
}
匿名内部类创建子类或实现类对象
class Test{
public void fun() {
System.out.println(“test ---- fun”);
}
}
interface InterA{
void fun();
}
public static void main(String[] args) {
Test test = new Test() {//相当于创建了Test类的子类的对象 并且没有类名
@Override
public void fun() {
// TODO Auto-generated method stub
System.out.println(“重写fun”);
}
};
test.fun();
//创建接口的实现类
InterA a = new InterA() {
//接口的实现类的对象
//注意:new 后面是类或者接口名
// {} 里面是 类或者接口中的方法
@Override
public void fun() {
// TODO Auto-generated method stub
System.out.println(“实现类 — fun”);
}
};
a.fun();
new InterA() {
@Override
public void fun() {
// TODO Auto-generated method stub
System.out.println(“泄泄”);
}
}.fun();;
}
匿名内部类 创建线程
public static void main(String[] args) {
//线程类的子类创建
Thread t1 = new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(“线程子类的run方法”);
}
};
t1.start();
//接口类的实现类创建线程
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("接口类的实现类的对象的 run方法");
}
};
//创建线程对象
Thread t2 = new Thread(runnable);
t2.start();
//合并
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("接口类的实现类的对象的 run方法");
}
});
t3.start();
}
线程的休眠方法(测试时常用)
线程的6大状态
- 线程调用了start方法得到了cpu的执行权 但必须得到CPU的执行资源才会进入运行状态
- 没有得到CPU执行资源的线程 会进入 受阻塞状态
- 当受阻塞状态的线程 得到了 CPU的执行资源
- 这是 会从受阻塞 ----> 运行状态
运行状态---->休眠状态 相当于 放弃了CPU的执行权
- 等到休眠时间到了 重新获得CPU的执行权
运行状态---->等待状态 相当于 放弃了CPU的执行权
- 等到调用了notify()方法 重新获得CPU的执行权
注意:wait()和notify()方法是 Object类中的方法
例:
class TestBThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
//休眠1秒
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + “----” + i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
//线程休眠
//单位:毫秒
//效果:卡住当前的线程
//注意:书写的位置 决定休眠那个线程
Thread.sleep(1000);
System.out.println(“我是main方法”);
TestBThread tb = new TestBThread();
tb.start();
}