1 线程的概念
1.1 线程与进程
这部分内容其实是属于《操作系统》这门课程的,接下来将详细的请看大佬的博客
操作系统常见面试题总结(上)
- 守护进程:备胎进程,就是当非守护进程执行完毕之后,守护进程会逐渐关闭,即还没有将任务完全执行完毕,也会提前关闭,当时守护进程不会立即关闭。
1.2 线程的实现

1.3 线程池
核心线程:线程池中最大线程数
队伍长度:排队等待的线程数量
临时线程:队伍排满后,才会创建临时线程
2 代码实践
2.1 继承 Thread 类
package cn.edu.njust.threaddemo;
public class MyThread extends Thread{
@Override
public void run() {
super.run();
for (int i = 0; i < 10; i++) {
System.out.println(getName() + ": 测试" + i);
}
}
}
package cn.edu.njust.threaddemo;
/**
* 第一种实现方式:继承Thread类别
*/
public class ThreadDemo01 {
public static void main(String[] args) {
// 创建线程
MyThread mt1 = new MyThread();
// 给线程指定名字
mt1.setName("线程1");
// 调用start()方法,开启线程
mt1.start();
// 创建第二个线程
MyThread mt2 = new MyThread();
// 指定名称
mt2.setName("线程2");
// 调用start()方法启动线程
mt2.start();
}
}
2.2 实现 Runnable 接口
package cn.edu.njust.threaddemo;
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
// 在这种实现方式中吗,不能直接调用getName()方法,需要先获取当前执行的线程
System.out.println(Thread.currentThread().getName() + ":测试" + i);
}
}
}
package cn.edu.njust.threaddemo;
/**
* 创建多线程的方式2:实现 Runnable 接口
*/
public class RunnableDemo01 {
public static void main(String[] args) {
// 创建任务对象
MyRunnable mr = new MyRunnable();
// 将任务交给线程
Thread t1 = new Thread(mr);
Thread t2 = new Thread(mr);
// 为线程设置名字,方便观察输出效果
t1.setName("线程1");
t2.setName("线程2");
// 启动线程,执行任务
t1.start();
t2.start();
}
}
2.3 实现 Callable 接口
package cn.edu.njust.threaddemo;
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
@Override
public Object call() throws Exception {
// 这个方法是有返回值的
int res = 0;
for (int i = 0; i < 10; i++) {
res += i;
}
return res;
}
}
package cn.edu.njust.threaddemo;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableDemo01 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建任务对象
MyCallable mc1 = new MyCallable();
// 创建 FutureTask 对象(用于管理多线程的运行结果)
FutureTask<Integer> futureTask = new FutureTask<>(mc1);
// 创建线程,用于执行任务
Thread t1 = new Thread(futureTask);
// 启动线程
t1.start();
// 获取结果
Integer ans = futureTask.get();
System.out.println("线程运行结果:" + ans);
}
}
2.4 线程安全
2.4.1 同步代码块
package cn.edu.njust.threadsafe;
/**
* 研究同步代码块的锁操作
*/
public class MyThread01 extends Thread {
private static int tickets = 0;
// 声明一个对象,用于给 synchronized 同步
private static final Object obj = new Object();
@Override
public void run() {
/*
不能这样写,这样写在多线程情况下会使得tickets数量超过100
因为这样写锁住的只是循环内部的东西
while (tickets < 100) {
//
synchronized (obj) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
tickets ++;
System.out.println(getName() + "已购买第" + tickets + "张票");
}
}*/
while (true) {
/*
* 这里可以使用 synchronized (obj),因为在成员变量中它被声明为了唯一的产量
* 当时真是开发中不会这样
* 一般都是对象所或者类锁,如下,直接获取.class对象,一定是唯一的
* */
// synchronized (obj) {
synchronized (Thread.class) {
if(tickets >= 100) break;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
tickets ++;
System.out.println(getName() + "已购买第" + tickets + "张票");
}
}
}
}
package cn.edu.njust.threadsafe;
public class ThreadTestDemo01 {
public static void main(String[] args) {
// 构造线程
MyThread01 mt1 = new MyThread01();
MyThread01 mt2 = new MyThread01();
MyThread01 mt3 = new MyThread01();
// 设置线程的名称
mt1.setName("客户1");
mt2.setName("客户2");
mt3.setName("客户3");
// 启动各个线程执行任务
mt1.start();
mt2.start();
mt3.start();
}
}
2.4.2 同步方法
package cn.edu.njust.threadsafe;
/**
* 同步方法
*/
public class MyRunnable implements Runnable {
private int tickets = 0;
@Override
public void run() {
while (true) {
if (!buyTickets()) break;
}
}
/**
* 这里锁的是 this,即谁调用,就锁住谁
* @return
*/
private synchronized boolean buyTickets() {
if (tickets >= 100) {
return false;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
tickets++;
System.out.println(Thread.currentThread().getName() + "购买了第" + tickets + "张票");
return true;
}
}
package cn.edu.njust.threadsafe;
public class ThreadTestDemo02 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr, "客户1");
Thread t2 = new Thread(mr, "客户2");
Thread t3 = new Thread(mr, "客户3");
t1.start();
t2.start();
t3.start();
}
}
2.5 线程池
2.5.1 静态方法创建
package cn.edu.njust.threaddemo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 线程池的基本创建
*/
public class ThreadPoolDemo01 {
public static void main(String[] args) {
// 创建没有上限的线程池,实际上是上线是int类型的最大值,但是实际计算机支持不了这么多
ExecutorService pool1 = Executors.newCachedThreadPool();
// 创建指定容量的现称池
ExecutorService pool2 = Executors.newFixedThreadPool(3);
// 提交任务,将线程任务交给线程池
/*pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());*/
pool2.submit(new MyRunnable());
pool2.submit(new MyRunnable());
pool2.submit(new MyRunnable());
pool2.submit(new MyRunnable());
pool2.submit(new MyRunnable());
// 销毁线程池
pool1.shutdown();
pool2.shutdown();
}
}
2.5.2 非静态方法
3 常用方法汇总
3.1 构造器
| ** 方法原型** | 说明 |
|---|---|
| public Thread() | 无参构造 |
| public Thread(String name) | 指定名字 |
| public Thread(Runnable target) | 指定任务 |
| public Thread(Runnable target, String name) | 可以在同时设置任务和设置名字 |
3.2 常用方法
| ** 方法原型** | 说明 |
|---|---|
| public final synchronized void setName(String name) | 为线程设置名字 |
| public final String getName() | 获取线程的名字 |
| public static native Thread currentThread() | 获取到当前正在执行的线程 |
| public static native void sleep(long millis) throws InterruptedException | 使当前进程休眠一定的时间,时间结束后自动苏醒 |
| public final void setPriority(int newPriority) | 设置优先级 |
| public final int getPriority() | 或许线程的优先级 |
| public final void setDaemon(boolean on) | 将一个线程设置为守护进程 |
| public static native void yield() | 出让线程 |
| public final void join() throws InterruptedException | 将一个线程插入到当前线程之前,插入的线程执行完毕之后再执行当前线程 |
3.3 线程池相关方法
| **方法原型 ** | 说明 |
|---|---|
| public static ExecutorService newCachedThreadPool() | 创建一个上限是 int 类型最大值的线程池 |
| public static ExecutorService newFixedThreadPool(int nThreads) | 创建指定容量的线程池 |
本文介绍了Java中的线程概念、进程与守护进程的区别、线程的实现方式(继承Thread、实现Runnable和Callable接口)、线程安全(同步代码块和同步方法)、以及线程池的创建(静态和非静态方法)。

被折叠的 条评论
为什么被折叠?



