进程与线程
进程: 一个正在运行的程序
一个进程中可以只有1个线程 单线程程序
一个进程中可以有多个线程 多线程程序
线程: 一个线程相当于一个CPU的执行路径(大大提升了处理效率)
一个独立运行的单元
public class Demo {
public static void main(String[] args) {
/*
* 标准的单线程程序
* 绝对安全 程序由上至下依次执行 效率不高
*/
// 添加
add();
//删除
remove();
System.out.println("程序执行完毕");
}
public static void add() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
public static void remove() {
System.out.println("删除");
}
}
代码是如何开启线程的
JVM调用main方法 --> 找操作系统(CPU) --> 开启一个执行路径
开启了一个叫 main 的执行路径 main 就是一个线程 main是线程的名字
又叫主线程
public class Demo02 {
public static void main(String[] args) {
// Exception in thread "main" 异常出现在 线程main 主线程中
System.out.println(10/0);
add();
System.out.println("程序完成");
}
public static void add() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}
创建一个线程 并开启
1. 需要集成Thread类
2. 重写父类中的 run方法
public class Demo{
public static void main(String[] args) {
// 创建一个线程
SubThread subThread = new SubThread("线程一");
SubThread subThread1 = new SubThread();
// 另一种给线程命名的方法
subThread1.setName("我是线程2");
// 如果直接调用run方法
// 相当于调用了一个普通的成员方法
// 这不是开启线程的方法
// subThread.run();
// 开启线程的方法
subThread.start();
subThread1.start();
// 这里会出现算术异常
// 但是运行时发现 主线程 main会报异常
// 而两个我们创建的线程不会报异常
System.out.println(10/0);
// 获取当前执行的线程对象的方法 静态方法
// 在哪个线程调 就获取哪个线程的名字
Thread currentThread = Thread.currentThread();
// 获取主线程的名字
System.out.println(currentThread.getName());
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "--main方法--" + " " + i);
}
}
}
// Thread(String name) 该方法在创建线程的同时给线程起个名字
// 构造方法不能被继承
// 要想使用父类的构造方法 可以在子类中写 带参数的构造方法
class SubThread extends Thread{
// 构造方法
public SubThread(){
}
public SubThread(String name){
// 调用父类的有参构造方法
super(name);
}
// 重写run方法
@Override
public void run() {
for (int i = 0; i < 50; i++) {
// 获取线程名的方法getName
System.out.println(getName() + "--run方法--" + " " + i);
}
}
}
/*
* 创建Thread子类 NameThread
* 要求:
* 成员变量 String name set/get方法 重写run方法
* 要有(带名字的)构造方法 无参的
*/
public class Demo {
}
class NameThread extends Thread{
private String name;
// 构造方法
public NameThread() {
}
public NameThread(String name, String myName) {
// 传递的是线程的名字
// 利用的是父类的构造方法
super(name);
// 给自己类的name赋值
// 建议:不要使用name这个名字 避免麻烦
this.name = myName;
}
/*
* 父类已经有了 getName()方法 并且用final修饰 不能被重写 所以报错
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
*/
// 解决方法 把set/get方法改名
public String getMyName() {
return name;
}
public void setMyName(String name) {
this.name = name;
}
}
接口实现方式来创建线程对象
public class Demo {
public static void main(String[] args) {
// 创建线程
RunnableImpl rI = new RunnableImpl();
Thread thread = new Thread(rI);
// 开启线程
thread.start();
}
}
// 接口中 run方法 是抽象方法
class RunnableImpl implements Runnable{
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
}
}
}