程序进程线程
1.进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。当我们使用迅雷,又启动了一个进程,操作系统将为迅雷分 配新的内存空间。
2.进程是程序的一次执行过程,或是正在运行的一个程序,是动态过程:有它自身的 产生、存在和消亡的过程
什么是线程
1.线程由进程创建的,是进程的一个实体
2.一个进程可以拥有多个线程
单线程和多线程
并发和并行
继承Thread创建线程
在java中线程来使用有两种方法。
1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法
package AAA;
public class Homework {
public static void main(String[] args) throws InterruptedException {
//创建Cat对象 可以当作线程使用
Cat cat = new Cat();
//启动线程
cat.start();
// cat.run();//run()只是一个普通的方法 没有真正的启动一个线程 就会把run()执行完毕 才会向下执行
//说明:当main线程启动一个子线程Thread-0, 主线程不会阻塞,会继续执行
for (int i = 0; i < 10; i++) {
System.out.println("主线程" + Thread.currentThread().getName());
//让主线程休眠
Thread.sleep(1000);
}
}
}
//1.当一个类继承了Thread 类, 该类就可以当做线程使用
//2.我们会重写run方法,写上自己的业务代码
//3. run Thread 类实现了Runnable 接口的run方法
/*
@Override
public void run() {
if (target != null) {
target . run();
}
}
*/
class Cat extends Thread {
int times = 0;
@Override
public void run() {//重写run方法 写上自己的业务逻辑
//加个while循环
while (true) {
//每隔一秒 输出
System.out.println("喵喵" + (++times) + "线程名" + Thread.currentThread().getName());
//让该线程休眠1秒 ctrl+alt+t
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (times == 80) {
break;
}
}
}
}
使用JConsole监控线程执行情况
为什么是start
run()只是一个普通的方法 没有真正的启动一个线程 就会把run()执行完毕 才会向下执行
就会变成这样:串行化
就是它要先把run()执行完毕 才会向下执行 如图
所以不能用cat.run();
start0() 是本地方法,是JVM调用, 底层是c/c++
实现真正实现多线程的效果的是start0(),而不是run
看源码就行 private native void start0();
start0方法调用start0()方法后,该线程并不-定会立马执行,只是将线程变成了可运行状态。具体什么时候执行,取决于CPU,由CPU统一调度。
Runnable创建线程
这里底层使用了设计模式【代理模式】
package AAA.junit;
public class ppppp {
public static void main(String[] args) {
Dog dog = new Dog();
//这里调用不了start
//创建 了Thread对象, 把dog对 象(实现RunnabLe) ,放入Thread
Thread thread = new Thread(dog);
thread.start();
}
}
class Dog implements Runnable {//通过实现RunnabLe接口,开发线程
int count = 0;
@Override
public void run() {
while (true) {
System.out.println("汪汪汪" + (++count) + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10) {
break;
}
}
}
}
静态代理
/* 代理:你帮我做事情 结果还是我的 把这个tiger给线程代理target -------> 12行 然后调用start()-------> 13行 就开始调用start0() ->start0()又调用run()-------> 54 58行 就会来到代理的这个run() -> 返回头去调用target target.run()马上进行动态绑定(运行类型Tiger) */
package AAA.junit;
public class ppppp {
public static void main(String[] args) {
// Dog dog = new Dog();
// //这里调用不了start
// //创建了Thread对象, 把dog对象(实现Runnable) ,放入Thread
// Thread thread = new Thread(dog);
// thread.start();
Tiger tiger = new Tiger();//实现了Runnable
ThreadProxy threadProxy = new ThreadProxy(tiger);//1.能把tiger放进去是因为它实现了Runnable接口
threadProxy.start();//3.再调用start()
}
}
class Animal {
}
class Tiger extends Animal implements Runnable {
@Override
public void run() {
System.out.println("老虎");
}
}
//线程代理类 模拟了一个极简的Thread类
/*
代理:你帮我做事情 结果还是我的
把这个tiger给线程代理target -------> 12行
然后调用start()-------> 13行
就开始调用start0() ->start0()又调用run()-------> 54 58行
就会来到代理的这个run() -> 返回头去调用target
target.run()马上进行动态绑定(运行类型Tiger)
*/
class ThreadProxy implements Runnable {//可以把Proxy类当做ThreadProxy
private Runnable target = null;//属性,类型是Runnable
@Override
public void run() {
if (target != null) ;
{
target.run();//动态绑定(运行类型Tiger)
}
}
//2.而这个构造器本身接收的就是Runnable这个接口类型
public ThreadProxy(Runnable target) {
this.target = target;
}
public void start() {
start0();
}
public void start0() {
run();
}
}
class Dog implements Runnable {//通过实现RunnabLe接口,开发线程
int count = 0;
@Override
public void run() {
while (true) {
System.out.println("汪汪汪" + (++count) + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10) {
break;
}
}
}
}
啊真的好神奇
先到这了,写的太长下次再来查找知识点的时候眼睛会看花的。