什么是进程?
什么是线程?
举个例子:人和房子
比如,现在有一个 100 平米的房子,这个房子就可以看做是一个进程。房子里有人,人就可以看做是一个线程。人在房子里做一些事,比如:吃饭、学习、睡觉,这个就好像现场在执行某个功能的代码。
进程和线程的区别?
什么是多线程?
比如:Tomcat就可以做并行处理,提升处理的效率,而不是一个一个排队。
再比如:要处理一个网络等待操作,开启一个线程去处理需要网络等待的任务,让当前业务线程可以继续往下执行逻辑,效率可以得到大幅度提升。
多线程的局限性?
什么是串行?
什么是并行?
什么是并发?
同步与异步?
阻塞与非阻塞?
同步阻塞:比如用锅烧水,水开后不会主动通知你;烧水开始执行后,需要一直等待水烧开。
同步非阻塞:比如用锅烧水,水开后不会主动通知你;烧水开始执行后,不需要一直等待水烧开,可以去执行一下其他的操作,但是需要时不时查看水开了没。
异步阻塞:比如用锅烧水,水开后会主动通知你水烧开了;烧水开始执行后,需要一直等待水烧开。
异步非阻塞:比如用锅烧水,水开后会主动通知你水烧开了;烧水开始执行后,不需要一直等待水烧开,可以去执行一下其他的操作。这个效果是最好的,平时开发时,提升效率最好的方式就是采用异步非阻塞的方式处理一些多线程的任务。
线程的创建分为三种方式:
public class MyTest {
public static void main(String[] args) {
MyJob t1 = new MyJob();
t1.start();
for (int i = 0; i < 100; i++) {
System.out.println("main:" + i);
}
}
}
class MyJob extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("MyJob:" + i);
}
}
}
public class MyTest {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread t1 = new Thread(runnable);
t1.start();
for (int i = 0; i < 1000; i++) {
System.out.println("main:" + i);
}
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("MyRunnable:" + i);
}
}
}
最常用的方式:
// 匿名内部类方式:
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("匿名内部类:" + i);
}
}
});
// Lambda 方式:
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
System.out.println("Lambda:" + i);
}
});
public class MyTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 创建 MyCallable
MyCallable callable = new MyCallable();
// 2. 创建 FutureTask,传入Callable
FutureTask task = new FutureTask<>(callable);
// 3. 创建 Thread 线程
Thread t1 = new Thread(task);
t1.start();
// 4. 启动线程
t1.start();
// 5. 做一些操作...
// 6. 获取结果
Object count = task.get();
System.out.println("总和为:" + count);
}
}
class MyCallable implements Callable {
@Override
public Object call() throws Exception {
int count = 0;
for (int i = 0; i < 100; i++) {
count += i;
}
return count;
}
}
网上对线程状态的描述有很多,有说 5 种的、6中的、7种的,都可以接受。
代码演示
public static void main(String[] args) {
Thread t1 = new Thread(() -> {});
System.out.println(t1.getState());
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
}
});
t1.start();
Thread.sleep(500);
System.out.println(t1.getState());
}
public static void main(String[] args) throws InterruptedException {
Object obj = new Object();
Thread t1 = new Thread(() -> {
// t1 线程拿不到锁资源,导致变为 BLOCKED状态
synchronized (obj) {
}
});
// main线程拿到obj的锁资源
synchronized (obj) {
t1.start();
Thread.sleep(500);
System.out.println(t1.getState());
}
}
public static void main(String[] args) throws InterruptedException {
Object obj = new Object();
Thread t1 = new Thread(() -> {
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread.sleep(500);
System.out.println(t1.getState());
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
Thread.sleep(500);
System.out.println(t1.getState());
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
Thread.sleep(1000);
System.out.println(t1.getState());
}
public static void main(String[] args) throws InterruptedException {
Thread currentThread = Thread.currentThread();
System.out.println(currentThread);
// "Thread[" + getName() + "," + getPriority() + "," + group.getName() + "]";
// Thread[main,5,main]
}
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
});
t1.setName("模块-功能-计数器");
t1.start();
}
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
System.out.println("t1: " + i);
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
System.out.println("t2:" + i);
}
});
t1.setPriority(1);
t2.setPriority(10);
t2.start();
t1.start();
}
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
if (i == 50) {
Thread.yield();
}
System.out.println("t1:" + i);
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
System.out.println("t2:" + i);
}
});
t2.start();
t1.start();
}
public static void main(String[] args) throws InterruptedException {
System.out.println(System.currentTimeMillis());
Thread.sleep(1000);
System.out.println(System.currentTimeMillis());
}
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("t1:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
for (int i = 0; i < 10; i++) {
System.out.println("main:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 1) {
try {
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("t1:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.setDaemon(true);
t1.start();
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
sync();
}, "t1");
Thread t2 = new Thread(() -> {
sync();
}, "t2");
t1.start();
t2.start();
Thread.sleep(12000);
synchronized (MyTest.class) {
MyTest.class.notifyAll();
}
}
private static synchronized void sync() {
try {
for (int i = 0; i < 10; i++) {
if (i == 5) {
MyTest.class.wait();
}
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
Thread.sleep(500);
t1.stop();
System.out.println(t1.getState());
}
static volatile boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (flag) {
// 处理任务
}
System.out.println("任务结束");
});
t1.start();
Thread.sleep(500);
flag = false;
}
public static void main(String[] args) throws InterruptedException {
// 线程默认情况下,interrupt标记位:false
System.out.println(Thread.currentThread().isInterrupted());
// 执行interrupt之后,再次查看打断信息
Thread.currentThread().interrupt();
// interrupt标记为:true
System.out.println(Thread.currentThread().isInterrupted());
// 返回当前下线程,并归位为 false,interrupt标记为:true
// 已经归位了
System.out.println(Thread.currentThread().isInterrupted());
// ====
Thread t1 = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 处理业务
}
System.out.println("t1结束");
});
t1.start();
Thread.sleep(500);
t1.interrupt();
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
// 获取任务
// 拿到任务,执行任务
// 没有任务了,让线程休眠
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("基于打断形式结束当前线程");
return;
}
}
});
t1.start();
Thread.sleep(500);
t1.interrupt();
}
wait 和 sleep 的区别?
wait 方法会将持有锁的线程从owner扔到WaitSet集合中,这个操作是在修改ObjectMonitor对象,如果没有持有synchronized锁的话,是无法操作ObjectMonitor对象的。