线程概念:
面试 #JinDRJ(什么是线程?)
- 进程:进程会获得操作系统给的资源和CPU调度。
- 线程:线程是独立获得CPU调度和操作系统资源分派的基本单位。
- 进程下包含了多个线程。
- 线程共享其所属进程的资源。
- 线程间相互竞争CPU调度,是CPU调度的最小单位。
- 进程间切换开销大,线程间切换开销小。
线程的状态:
线程间关系
并发:
多个线程在运行,但每个时刻只有一个线程运行。(⭐强调一起出发)并行:
物理意义上的同时执行。(⭐强调一起执行)同步:
意义:线程间共享资源,但部分资源一次最好是仅一个线程使用(如打印机打印),所以需要 同步,使得线程排队,而不混乱。
Java提供的方法:
synchronized(object1){ //阻塞需要加锁,锁的对象应该是括号里配置的 名为 object1 的实例对象try {object1.wait(); //阻塞了当前对象对象后面的线程} catch(InterruptedException e) {// //}}
synchronized(object1) {object1.notify(); //将唤醒 一个 线程}
synchronized(this) {this.notifyAll(); //将唤醒 所有 线程参与竞争}
创建一个线程
Java 提供了三种创建线程的方法:
- 通过实现
Runnable接口; - 通过继承
Thread类本身; -
实现
Runnable接口来创建线程具体实现:
类
RunnableA实现Runnable接口;- 重写
run(),这是接口的要求; new Thread(RunnableA,"threadName");,创建线程;-
Runnable实际代码:```java class RunnableDemo implements Runnable { private Thread t; //其实还是得依托Thread类来拉起线程 这里的实例中的start()函数需要,所以写在类内部 private String threadName;
RunnableDemo( String name) { //规定名字 threadName = name; }
@Override public void run() { for(int i = 4; i > 0; i—) {
System.out.println("Thread: " + threadName + ", " + i);
} }
public void start () { //本实例封装了new Thread(),且threadName在Main中创建本类时已传入 if (t == null) {
t = new Thread (this, threadName); //重要,t.start ();
} } }
public class Main {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( “Thread-1”);
R1.start();
RunnableDemo R2 = new RunnableDemo( “Thread-2”);
R2.start();
}
}
<a name="UQmKY"></a>#### 继承`Thread`来创建线程<a name="wmEef"></a>##### 具体实现:1. 类`ThreadA`继承`Thread`类;1. 重写`run()`,实现核心代码;1. `new Thread(threadA,"threadName");`实现线程的创建;1. `thread.start();`实现线程的拉起。<a name="YsUq3"></a>##### `Thread`实际代码:```javaclass ThreadDemo extends Thread {private Thread t;private String threadName;ThreadDemo( String name) {threadName = name;}public void run() {for(int i = 4; i > 0; i--) {System.out.println("Thread: " + threadName + ", " + i);}}public void start () { //封装了真正拉起线程的 thread.start()if (t == null) {t = new Thread (this, threadName);t.start ();}}}public class Main {public static void main(String args[]) {ThreadDemo T1 = new ThreadDemo( "Thread-1");T1.start();ThreadDemo T2 = new ThreadDemo( "Thread-2");T2.start();}}
使得主线程等待子线程的执行:
thread.join();将使得主线程等待名为thread的子线程的执行完成,才继续执行。
所以,
- 如果多个子线程,一个
.start();马上又.join();,将使得程序退变为单线程。 - 子线程全都先
.start();,之后再都.join();,此时,子线程间将异步执行,但主线程等待join()的全部子线程。实现
Callable接口创建线程
三种创建线程方法的对比:
- 采用实现
Runnable、Callable接口的方式创建多线程时,线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。 - 使用继承
Thread类的方式创建多线程时,编写简单(因为最终都是使用new Thread(T,"threadName");拉起线程的),如果需要访问当前线程,直接使用this即可获得当前线程。
Java线程关键字:
volatile(adj.不稳定的)(wa_al-tou)
volatile用法:
volatile意义:
- 表示这个变量的修改将立即写入主存;
表示对这个变量的读取将直接从内存读取,而不是 CPU 寄存器。
synchronized(v.同步,使在时间上一致)(syn-k_rui-nized)
synchronized用法:加锁 代码块:
synchronized(this) { //唤醒也必须加锁,加锁的对象应该是需要执行唤醒操作的对象this.notify(); //将唤醒 一个 线程}
加锁 整个函数:
public synchronized void test() {for (int i = 0; i < 5; i++) {System.out.println("线程名:"+Thread.currentThread().getName() + ":" + (count++));}}
synchronized意义:字面意思:同步;
- 当一个线程在访问
synchronized中的内容时,其他想访问 此内容 的线程将被阻塞; 对于普通方法,锁是当前实例对象(
this),对于静态同步方法,锁是当前类的class对象。Java线程相关方法:
Thread.sleep(long millisec);:-
object.wait();: -
object.notify();: -
object.notifyAll();: 唤醒对象等待池所有线程参与竞争。
Thread.sleep(long millisec);和object.wait();的区别:
🐵 #面试 #JinXD
Thread.sleep(long millisec);不释放对象锁,object.wait();释放对象锁;object.wait();要搭配object.notify();或者object.notifyAll();来唤醒。
