多线程学习-day-01多线程基础

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Xgx120413/article/details/83045899

线程基础、线程之间的共享和协作

(目前会将一些概念简单描述,一些重点的点会详细描述)

1,CPU核心数和线程数之间的关系

①、一块CPU只有一块处理器

②、Inter提出了多核处理器

③、CPU核心数 和 线程数 是 1:1 的关系

④、Inter提出了超线程,CPU核心数 和 线程数 是 1:2 的关系

⑤、CPU同一时间只能运行16个线程

2、CPU时间片轮转机制

①、RR调度:首先将所有就绪的队列按FCFS策略排成一个就绪队列,然后系统设置一定的时间片,每次给队首作业分配时间片。如果此作业运行结束,即使时间片没用完,立刻从队列中去除此作业,并给下一个作业分配新的时间片;如果作业时间片用完没有运行结束,则将此作业重新加入就绪队列尾部等待调度。

②、CPU时间片轮转机制可能会导致上下文切换。

3、什么是进程和线程?

①、进程是程序运行资源分配的最小单位。进程内部有多个线程,会共享这个进程中的资源。

②、线程是CPU调度的最小单位。必须依赖进程而存在。

4、并行和并发的区别?

①、并行:同一时刻,可同时处理问题的能力。比如售票窗口多开,多开的窗口表示同时处理的能力。

②、并发:与单位时间相关,在单位时间内处理事情的能力。

5、高并发编程的意义、好处和注意事项

①好处:充分利用CPU资源,加快用户响应时间,程序模块化,异步化。

②问题:A、线程共享资源,存在冲突;B、容易导致死锁;C、启用太多线程,可能会搞垮机器。

6、学习多线程

①、Java里的程序天生就是多线程的。

        A、ThreadMXBean是Java虚拟机为我们提供线程管理的接口,通过该类可以拿到应用中有多少个线程。

        B、至少会运行5个线程:

                1、main主函数线程
                2、Reference Handler负责清除引用的线程
                3、Finalizer调用对象的Final方法的线程
                4、Signal Dispatcher分发,处理发送给虚拟机信号的线程
                5、Attach Listener获取当前程序运行相关信息

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class OnlyMain {

	public static void main(String[] args) {

		// Java虚拟机 为我们提供的线程里面,线程管理的接口,通过该类可以拿到应用程序里面有多少个线程
		ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
		// 是否看锁,这里不看锁,一般用不到,返回值是ThreadInfo的数组
		ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
		// 遍历数组
		for (ThreadInfo threadInfo : threadInfos) {
			/**
			 *  main主函数线程
			 *  Reference Handler负责清除引用的线程
			 *  Finalizer调用对象的Final方法的线程
			 *  Signal Dispatcher分发,处理发送给虚拟机信号的线程
			 *  Attach Listener获取当前程序运行相关信息
			 */
			System.out.println("【" + threadInfo.getThreadId() + "】 " + threadInfo.getThreadName());
		}
	}
}

控制台输出:
【5】 Attach Listener
【4】 Signal Dispatcher
【3】 Finalizer
【2】 Reference Handler
【1】 main

        C、实现多线程的三种方式及区别:

                1、继承Thread类

                2、实现Runnable接口

                3、实现Callable接口,允许有返回值,并且不能直接用new Thread来启动该多线程接口对象,而是需要先用FutureTask对象来转换一次,再调用new Thread()来启动Callable多线程对象

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class NewThread {

	/* 扩展自Thread类 */

	/* 实现Runnable接口 */
	private static class UseRunnable implements Runnable {

		@Override
		public void run() {
			System.out.println("It is a Runnable!");
		}

	}

	/* 实现Callable接口,允许有返回值 */
	private static class UseCallable implements Callable<String> {

		@Override
		public String call() throws Exception {
			System.out.println("It is a Callable!");
			return "CallableResult";
		}
	}

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		// 实例化Runnable接口对象
		UseRunnable useRunnable = new UseRunnable();
		// 通过new Thread来执行Runnable多线程对象
		new Thread(useRunnable).start();

		// 实例化Callable接口对象
		UseCallable useCallble = new UseCallable();
		// Thread不能够运行Callable接口对象,只能通过FutureTask接口转换后在运行
		FutureTask<String> futureTask = new FutureTask<>(useCallble);
		new Thread(futureTask).start();
		System.out.println(futureTask.get());
	}
}

控制台输出:
It is a Runnable!
It is a Callable!
CallableResult

来自享学IT教育课后总结。

猜你喜欢

转载自blog.csdn.net/Xgx120413/article/details/83045899
今日推荐