1. 并发,并行,线程,进程
并发:多件事情在同一时间段内发生
例如:一个人在10分钟内,一边喝水,一边看电视,一边吃饭,
并行:多件事情在同一时刻发生
例如:A和B同时(同时同分同秒)在工作。
进程:指一个应用程序在操作系统执行,例如:QQ,浏览器,微信等。
线程:一个进程的最小执行单元,一个进程最少有一个线程,可以有多个线程。
线程的调度方式
分时调度: 多个线程使用CPU的时间是相同的。
抢占式调度:多个线程抢占cpu,哪个线程抢到,哪个就运行。
一个cpu只能执行一个线程,当电脑上同时运行多个应用程序的时候,cpu的频繁的切换线程,在宏观角度看像是同时运行多个程序,但在微观上看是串行执行的。
如果是多个cpu,那么就能实现并行执行。
2. 创建线程
继承Thread类
i
继承Thread类,重写run方法,创建Therad子类示例,调用start方法。
public class OneThread {
public static void main(String[] args) {
//3.创建一个Thread子类示例
TwoThread twoThread = new TwoThread();
//4.调用start方法
twoThread.start();
for (int i = 0; i < 20; i++) {
System.out.println("one 主线程" + i);
}
}
}
// 1.创建Thread子类
class TwoThread extends Thread {
//2. 重写run方法
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("Two 子线程" + i);
}
}
}
执行结果如上图,因为一个cpu在同一时刻只能执行一个线程,所以多个线程时哪个线程抢到资源会执行哪个线程。
如果是调用run方法,那么就不会创建新的线程,只有一个主线程。执行结果如下图。
实现Runnable
1.创建一个类实现Runnable接口
2.重写run方法
3.创建Runnable接口实现类的实例
4.用twoRunnable 作为target 创建一个Thread示例,
5.调用start方法
public class OneThread {
public static void main(String[] args) {
//3.创建Runnable接口实现类的实例
TwoRunnable twoRunnable = new TwoRunnable();
//4.用twoRunnable 作为target 创建一个Thread示例,
Thread thread = new Thread(twoRunnable);
//5.调用start方法
thread.start();
for (int i = 0; i < 5; i++) {
System.out.println("one 主线程" + i);
}
}
}
//1.创建一个类实现Runnable接口
class TwoRunnable implements Runnable{
//2. 重写run方法
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Runnable 子线程" + i);
}
}
}
Runnable接口可以用来实现:多个相同的程序代码线程共享同一个资源。
如下: 创建一个 c 的共享资源,创建两个线程,去对c修改。
public class OneThread {
public static void main(String[] args) {
TwoRunnable twoRunnable = new TwoRunnable();
Thread thread = new Thread(twoRunnable,"1");
Thread thread2 = new Thread(twoRunnable,"2");
thread.start();
thread2.start();
}
}
class TwoRunnable implements Runnable{
private int c = 8;
@Override
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println( "第 "+Thread.currentThread().getName() + "个线程" + c--);
}
}
}
当然继承Thread 也可以,声明变量c:
private static int c = 8;
继承Thread和实现Runnable接口有什么不一样:
- java 是单继承,如果继承了Thread就没办法继承其他的类,如果是实现Runnale接口那么就可以继承其他类。
- Runnable 可以更便捷的共享同一个资源。
- 增强代码的健壮性,同一个代码可以被多个线程共享,实现代码和线程的解耦。
3. 线程常用方法
线程的优先级
public final void setPriority(int newPriority)
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
可以通过setPriority()设置线程的优先级,该参数是1到10,最大是10 最小是1。优先级:不能决定线程一定会先执行,只能反映线程紧急程度。
休眠
可以指定线程睡眠的毫秒数: Thread.sleep(1000);
public static native void sleep(long millis) throws InterruptedException;
设置让步
Thread.yield();
暂停当前正在执行的线程对象(放弃当前占有的cpu资源),回到可运行状态,重新去竞争cpu资源,所以在实际中可能达不到 yield() 让步的目的。
合并
public final void join() throws InterruptedException {
join(0);
}
thread2.join();
当主线程执行的时候,子线程调用join()方法,这时候主线程会等待 子线程执行完再执行。
守护线程
主线程结束,守护线程也自动结束,垃圾回收器线程属于守护线程。
thread2.setDaemon(true); // 设置守护线程
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情