概述
本文章为 javaEE初阶 教学
下一篇文章为:面试八股文,多线程进阶!点击这里进行跳转
通过此文章可以学习到:
1、计算机是如何工作的
2、什么是操作系统
3、什么是进程
4、操作系统如何管理进程
5、什么是PCB
6、PCB中的一些属性
7、什么是线程
8、线程和进程的区别
9、java中的Thread类用法
文章目录:
1、了解什么是API
2、关于操作系统
3、进程(跑起来的程序)
4、操作系统如何管理进程
5、PCB中的一些属性
6、进程的调度与隔离性
7、线程
8、经典面试题(线程和进程的区别)
9、Java中的 Thread 类
- 9.1、五种创建方法
- 9.2、多线程的作用
- 9.3、其他属性和方法
- 9.4.、java中的一些重要的方法
- 9.4.1、run方法
- 9.4.2、中断线程
- 9.4.3、线程等待
- 9.4.4、获取当前线程的名字
- 9.4.5、线程休眠
10、线程的状态
- 10.1、NEW
- 10.2、TERMINATED
- 10.3、RUNNABLE
- 10.4、TIME_WAITING
- 10.5、BLOCK
- 10.6、WAITING
11、线程安全
- 11.1、什么情况下认为线程是安全的
- 11.2、一个线程不安全的典型案例
- 11.3、如何解决线程安全问题
- 11.4、产生线程不安全的原因
- 11.5、synchronized的用法
12、什么是可重入
- 12.1、什么是死锁
- 12.2、死锁的其他场景
- 12.3、死锁的四个条件
13、标准库
14、针对于内存可见性的另外一种解释
15、缓存
16、volatile 和 synchronized区别(仅针对于java)
17、wait 和 notify
18、线程安全的单例模型
- 18.1、饿汉模型
- 18.2、懒汉模型
19、阻塞队列实现—生产者消费者模型
20、定时器的模拟实现
21、线程池的模拟实现
1、了解什么是API
2、关于操作系统
3、进程(跑起来的程序)
4、操作系统如何管理进程
操作系统管理进程大体分为两部分:
- 1、先描述一个进程
- 2、再组织若干个进程(使用一些数据结构,把很多描述进程的信息放到一起,方便进行增删改查)
5、PCB的一些属性
①、pid(进程的身份标识)
②、内存指针(指明即将执行的代码和指令在内存的哪里,以及这个进程执行中依赖的数据的位置)
那问题来了为什么需要这样一个内存指针
③、文件描述符表(程序的运行和文件息息相关)
上述PCB属性:
所谓进程调度:
例如:
这就是所谓的进程调度
在理解下面一组属性我们先需要了解一组知识:并发和并行
下面正式介绍PCB的下一组属性
通过一个小故事我们来理解一下这四个属性
①、状态
②、优先级
③、记账信息
④、上下文
通过这个例子我们就可以清楚的理解这四个PCB的属性了
6、进程的调度与隔离性
这里的知识我们再举个例子:
7、线程
8、经典面试题:线程与进程的区别
- 1、进程包括线程,一个进程可以有一个或多个线程
- 2、进程和线程是为了处理并发编程这样的场景,但是进程创建和销毁的开销较大,效率较低,相比之下,进程更加轻量,创建和销毁的效率更高(轻量是因为少了申请释放的过程)
- 3、操作系统创建进程,要给进程分配资源,进程是操作系统分配资源的基本单位,操作系统创建线程,是要在CPU上调度执行的,线程是操作系统调度执行的基本单位
- 4、进程具有独立性,每个进程有独自的虚拟地址空间,一个进程挂了,一般不会影响到其他进程,同一个进程中的多个线程,由于是公用一个内存空间,一个线程挂了,甚至导致整个进程崩溃
9、Java中的 Thread 类
Thread类是什么?
9.1、五种创建方法
①、创建子类,继承于Thread
class MyThread extends Thread{
@Override
public void run() {
System.out.println("这是一个线程");
}
}
public class Test {
public static void main(String[] args) {
Thread t = new MyThread();
t.start();
}
}
②、创建一个类实现Runable接口再创建实例传给Thread类
class MyRunable implements Runnable{
@Override
public void run() {
System.out.println("这是一个线程");
}
}
public class Test {
public static void main(String[] args) {
Thread t = new Thread(new MyRunable());
t.start();
}
}
③、使用匿名内部类,简化方法1
public class Test {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
System.out.println("这是一个线程");
}
};
t.start();
}
}
④、使用匿名内部类,简化方法2
public class Test {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("这是一个线程");
}
});
t.start();
}
}
⑤、使用lambda表达式进一步简化
public class Test {
public static void main(String[] args) {
Thread t = new Thread(()-> System.out.println("这是一个线程"));
t.start();
}
}
9.2、多线程的作用
先看一个串行的代码:
虽然通过上述的代码可以发现执行效率显著提升,但也要注意一个问题;
9.3、其他属性和方法
①、为线程起别名
②、是否后台进程
上述代码的t1,t2都是前台进程:
③、是否存活
9.4、Thread中的一些方法
9.4.1、run方法
9.4.2、中断线程
①、手动设置标志位
②、使用线程中的方法设置标志位
public class Test2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
while(!Thread.currentThread().isInterrupted()){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
public class Test2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
while(!Thread.currentThread().isInterrupted()){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
});
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
9.4.3、线程等待
两个版本:一个-----线程等待没有时间限制(死等)
另外一个版本:有时间限制
9.4.4、获取当前线程的名字
9.4.5、线程休眠
10、线程的状态
10.1、NEW
10.2、TERMINATED
10.3、RUNNABLE
10.4、TIME_WAITING
10.5、BLOCK
10.6、WAITING
总结:
11、线程安全
11.1、什么情况下认为线程是安全的
11.2、一个线程不安全的典型案例
11.3、如何解决线程安全问题
11.4、产生线程不安全的原因
11.5、synchronized的用法
总结上述知识:
12、可重入
12.1、什么是死锁
这样的问题就是死锁
所以在设计synchronized的时候:
12.2、死锁的其他使用从场景
12.3、死锁的四种必要条件
13、标准库
14、针对于内存可见性的另外一种解释
15、缓存
16、volatile和synchronized区别(仅针对于java)
17、wait 和 notify
18、单例模型
预备知识:
18.1、饿汉模型
/**
* Created with IntelliJ IDEA.
* Description:
* User: Lenovo
* Date: 2022-03-31
* Time: 9:29
*/
//线程安全的单例模型
//1、饿汉模型
class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){};
public static Singleton getInstance() {
return instance;
}
}
public class Demo {
public static void main(String[] args) {
Singleton instane = Singleton.getInstance();
}
}
18.2、懒汉模型
/**
* Created with IntelliJ IDEA.
* Description:
* User: Lenovo
* Date: 2022-03-31
* Time: 9:31
*/
//线程安全的单例模型 懒汉模型
class Singleton2{
private volatile static Singleton2 instance = null;
private Singleton2(){};
public static Singleton2 getInstance() {
if(instance == null){
synchronized (Singleton2.class){
if(instance == null){
instance = new Singleton2();
}
}
}
return instance;
}
}
public class Demo2 {
public static void main(String[] args) {
Singleton2 instance = Singleton2.getInstance();
}
}
19、阻塞队列实现—生产者消费者模型
/**
* Created with IntelliJ IDEA.
* Description:
* User: Lenovo
* Date: 2022-03-31
* Time: 9:34
*/
//通过阻塞队列实现生产者消费者模型
class MyBlockingQueue{
private int[] data = new int[1000];
private int head = 0;
private int tail = 0;
private int size = 0;
private Object locker = new Object();
public void put(int val) throws InterruptedException {
synchronized (locker){
if(size == data.length){
locker.wait();
}
data[tail] = val;
tail++;
if(tail >= data.length){
tail = 0;
}
size++;
locker.notify();
}
}
public Integer take() throws InterruptedException {
synchronized (locker){
if(size == 0){
locker.wait();
}
int ret = data[head];
head++;
if(head >= data.length){
head = 0;
}
size--;
locker.notify();
return ret;
}
}
}
public class Demo3 {
public static void main(String[] args) {
MyBlockingQueue qu = new MyBlockingQueue();
Thread produce = new Thread(()->{
int num = 0;
while(true){
System.out.println("生产了:"+num);
try {
qu.put(num);
num++;
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
produce.start();
Thread consumer = new Thread(()->{
while(true){
try {
int num = qu.take();
System.out.println("消费了:"+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumer.start();
}
}
20、模拟实现定时器
import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue;
/**
* Created with IntelliJ IDEA.
* Description:
* User: Lenovo
* Date: 2022-03-31
* Time: 10:09
*/
//先描述一个任务
class MyTask{
//任务具体是什么
private Runnable runnable;
//任务完成的具体时间
private long time;
//给任务初始化
public MyTask(Runnable runnable,long delay){
this.runnable = runnable;
this.time = System.currentTimeMillis() + delay;
}
//执行任务
public void run(){
runnable.run();
}
public long getTime() {
return time;
}
}
//组织这些任务
class MyTimer {
//使用带有优先级的阻塞队列
PriorityBlockingQueue<MyTask> qu = new PriorityBlockingQueue<>(10, new Comparator<MyTask>() {
@Override
public int compare(MyTask o1, MyTask o2) {
return (int) (o1.getTime() - o2.getTime());
}
});
//把任务放到阻塞队列中
public void schedule(Runnable runnable, long delay) {
MyTask myTask = new MyTask(runnable, delay);
//这里成功放一个元素就通知一下
qu.put(myTask);
synchronized (locker) {
locker.notify();
}
}
private Object locker = new Object();
//创建一个扫描贤臣去寻找先执行的任务
public MyTimer(){
Thread t = new Thread(() -> {
while (true) {
try {
MyTask myTask = qu.take();
long curTime = System.currentTimeMillis();
//这里会造成忙等
if (curTime < myTask.getTime()) {
qu.put(myTask);
//等待差值的时间
synchronized (locker) {
locker.wait(myTask.getTime() - curTime);
}
} else {
myTask.run();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
public class Demo4 {
public static void main(String[] args) {
MyTimer myTime = new MyTimer();
myTime.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello timer");
}
},3000);
System.out.println("main");
}
}
21、模拟实现线程池
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Created with IntelliJ IDEA.
* Description:
* User: Lenovo
* Date: 2022-03-31
* Time: 10:18
*/
//模拟实现线程池
class MyThreadPool{
//创建任务并使用阻塞队列组织任务
private BlockingQueue<Runnable> qu = new LinkedBlockingQueue<>();
//创建一个工作类线程
static class Worker extends Thread{
private BlockingQueue<Runnable> qu = null;
public Worker(BlockingQueue<Runnable> qu){
this.qu = qu;
}
public void run(){
while(true){
//从阻塞队列中取出来一个任务执行
try {
Runnable runnable = qu.take();
runnable.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//把执行好的线程组织在顺序表中
List<Thread> workers = new ArrayList<>();
public MyThreadPool(int n){
for (int i = 0; i < n; i++) {
Worker worker = new Worker(qu);
worker.start();
workers.add(worker);
}
}
//把任务提交到阻塞队列中
public void submit(Runnable runnable) throws InterruptedException {
qu.put(runnable);
}
}
public class Demo5 {
public static void main(String[] args) throws InterruptedException {
MyThreadPool pool = new MyThreadPool(10);
for (int i = 0; i < 100; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello pool");
}
});
}
}
}
最后
以上就是无语小熊猫为你收集整理的JavaEE初阶----多线程初阶----Thread 1、了解什么是API 2、关于操作系统 3、进程(跑起来的程序) 4、操作系统如何管理进程 5、PCB的一些属性 在理解下面一组属性我们先需要了解一组知识:并发和并行 6、进程的调度与隔离性 7、线程 8、经典面试题:线程与进程的区别 9、Java中的 Thread 类 10、线程的状态 11、线程安全 的全部内容,希望文章能够帮你解决JavaEE初阶----多线程初阶----Thread 1、了解什么是API 2、关于操作系统 3、进程(跑起来的程序) 4、操作系统如何管理进程 5、PCB的一些属性 在理解下面一组属性我们先需要了解一组知识:并发和并行 6、进程的调度与隔离性 7、线程 8、经典面试题:线程与进程的区别 9、Java中的 Thread 类 10、线程的状态 11、线程安全 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复