一、程序
例如QQ、微信等这样的应用,即是程序。
二、进程
进程就是一个程序运行起来的状态。
三、线程
线程是一个进程中不同的执行路径。
专业一点的解释:
进程是OS分配资源的基本单位,线程是执行调度的基本单位。分配资源最重要的是:开辟独立的内存空间,线程再调度执行(即线程共享进程的内存空间,没有自己独立的内存空间)
四、纤程/协程
纤程是用户态的线程,线程中的线程;纤程的切换和调度不需要经过内核,而线程的切换是在内核态完成的。
1、与线程相比,纤程特点
1)占有资源少,一般OS的线程占用1M,纤程4K
【线程相关的一些基本概念】2)切换比较简单
五、创建线程的方法
1、继承Thread类
2、实现Runnable接口
3、通过Executor线程池创建
/**
* @author Java和算法学习:周一
*/
public class CreateThread {private static class MyThread extends Thread {
@Override
public void run() {
System.out.println("MyThread");
}
}private static class MyRun implements Runnable {
@Override
public void run() {
System.out.println("MyRun");
}
}public static void main(String[] args) {
new MyThread().start();
new Thread(new MyRun()).start();
new Thread(()->{
System.out.println("lambda...");
}).start();
}}
六、线程常用的方法 1、Sleep方法 让出当前执行的线程,给别的线程去运行
2、Yield方法 谦让的退出一下,即让出CPU一下;此线程会到线程的等待队列里,CPU有可能会再次执行该线程,但更大的可能是执行其他的线程。
3、Join方法 停止执行当前的线程,转而去执行join的线程
/**
* @author Java和算法学习:周一
*/
public class SleepYieldJoin {public static void main(String[] args) {
//testSleep();
//testYield();
testJoin();
}static void testSleep() {
new Thread(() -> {
for (int i = 0;
i < 10;
i++) {
System.out.println("SleepA" + i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
for (int i = 0;
i < 100;
i++) {
System.out.println("SleepB" + i);
}
}).start();
}static void testYield() {
new Thread(() -> {
for (int i = 0;
i < 10;
i++) {
System.out.println("yieldA" + i);
if (i % 2 == 0) {
Thread.yield();
}
}
}).start();
new Thread(() -> {
for (int i = 0;
i < 10;
i++) {
System.out.println("yieldB" + i);
if (i % 2 == 0) {
Thread.yield();
}
}
}).start();
}static void testJoin() {
Thread t1 = new Thread(() -> {
for (int i = 0;
i < 10;
i++) {
System.out.println("A" + i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}for (int i = 0;
i < 10;
i++) {
System.out.println("B" + i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3 = new Thread(() -> {
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}for (int i = 0;
i < 10;
i++) {
System.out.println("c" + i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//不管t1、t2、t3启动顺序怎样,输出结果都一样,这就可以保证t1、t2、t3按顺序执行
t3.start();
t2.start();
t1.start();
}}