线程和进程
进程:一个正在进行的程序就是一个进程
线程:一个进程中有很多个线程
(每一个线程相当于执行的任务)
开启一个线程 相当于开启了一个CPU的执行路径(相对独立)
CPU在执行多个线程时是随机的 跟线程的优先级有关
分时调度 CPU会在多个线程中进行随机切换
标准的单线程程序
特点:程序由上至下依次执行
(一个执行完才回去执行下一个)
好处:数据绝对安全
弊端:效率不高
public class Demo01 {
public static void main(String[] args) {
add();
delete();
System.out.println("程序执行完了");
}
public static void add() {
for (int i = 0; i < 100; i++) {
System.out.println("add---"+i);
}
}
public static void delete() {
for (int i = 0; i < 100; i++) {
System.out.println("add---"+i);
}
}
}//依次执行
主线程
多线程的程序除了主线程以外 一般都叫子线程
一个程序只有一个主线程
main函数就是一个线程 并且是主线程
主线程(叫main的线程)是如何被执行的
JVM调用main函数-->CPU就为叫main的函数开辟一个执行路径
-->相当于在这个执行路径中执行main函数中的代码
Thread线程类(开辟一个主线程以外的线程 子线程)
1.创建一个Thread类的子类
2.重写run方法
run方法就是你要线程执行的代码
3.调用start方法开启线程(不能重复开启)
public class Demo02 {
public static void main(String[] args) {
//创建一个子线程
//开启多个线程时 多个线程会同时执行
//并且是相对的独立执行单元
subThread subThread=new subThread();
//开启线程
subThread.start();
//再开一个子线程
subThread subThread1=new subThread();
subThread1.start();
//主线程 出现异常了 但是并没有影响子线程的执行
System.out.println(10/0);
//主线程
for (int i = 0; i < 100; i++) {
System.out.println("main---"+i);
}
}
}
//声明一个线程类
class subThread extends Thread{
//重写run方法
@Override
public void run() {
//子线程默认的名字 Thread-X
//X是从0开始的
for (int i = 0; i < 100; i++) {
System.out.println("run---"+i);
}
//子线程 执行的代码
System.out.println("我是子线程");
}
}
设置线程名字
NameThread t1=new NameThread("哈哈");
t1.setName("线程--1");
获取当前正在执行的线程
Thread currentThread = Thread.currentThread();
System.out.println(currentThread.getName());
创建一个线程 相当于cpu开辟了一个独立路径
相当于开辟一个独立的方法栈来专门运行子线程中的方法
TestThread thread=new TestThread();
thread.start();
匿名内部类方式创建线程
匿名内部类创建出来的对象是该类的子类对象
public class Demo07 {
public static void main(String[] args) {
//fun1();
//直接创建接口类的实现类对象
//注意:这种方式new后面跟的是父类名
//但创建出来的对象却是子类或实现类的对象
Testinter testinter=new Testinter() {
@Override
public void fun() {
System.out.println("我是实现类的fun方法");
}
};
testinter.fun();
}
private static void fun1() {
//new Test() {}; 相当于是Test类的子类对象
//并且在后面的大括号中可以重写父类中的方法
Test test=new Test() {
//重写fun方法
@Override
public void fun() {
System.out.println("我是匿名内部类中重写的fun方法");
}
};
test.fun();
}
}
线程的创建方式
public class Demo09 {
public static void main(String[] args) {
//方式1(用Thread子类的方法)
Thread thread=new Thread() {
@Override
public void run() {
System.out.println("子线程执行的方法");
}
};
thread.start();
//方式2(接口实现类的方式)
Runnable runnable=new Runnable() {
@Override
public void run() {
System.out.println("子线程方法");
}
};
Thread t2=new Thread(runnable);
t2.start();
//方式3
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程方法");
}
}).start();
}
}
线程休眠(测试线程代码的时候比较常用)
线程状态(6种)
线程调用start()方法就一定会变成运行状态吗?
不一定调用start()方法表示该方法可以被cpu执行
但是cpu不一定来执行 所以不一定变成运行状态
需要等待cpu的执行 这种状态叫做受阻塞状态
1.新建状态(new thread)
2.运行状态(start())
3.死亡状态(run方法运行完毕)
4.受阻塞状态(cpu未执行该线程时)
5.休眠状态(sleep方法 休眠时间过了 恢复)
6.等待状态(wait notify)
public class Demo10 {
public static void main(String[] args) throws InterruptedException {
//主线程休眠
//参数时休眠时间 单位毫秒
//卡住主线程1秒钟
//休眠时间结束会自动醒来
//Thread.sleep(1000);
//System.out.println("哈哈哈");
TestA testA=new TestA();
testA.start();
}
}
class TestA extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//休眠
//父类中run方法没抛异常
//子类只能try--catch处理
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
}