目录
[Java 开启线程的方式](#Java 开启线程的方式)
多线程
进程和线程
进程介绍
进程 (Process) 是计算机中的程序关于某数据集合上的一次运行活动
是系统进行资源分配的基本单位
简单理解:程序的执行过程
独立性:每一个进程都有自己的空间,在没有经过进程本身允许的情况下,一个进程不可以直接访问其它的的进程空间
动态性:进程是动态产生,动态消亡的
并发性:任何进程都可以同其它进程一起并发执行

并行和并发
并行:在同一时刻,有多个指令在多个CPU上【同时】执行
并发:在同一时刻,有多个指令在单个CPU上【交替】执行
进程介绍
多进程同时执行

多进程同时执行

进程(Process):程序的执行过程
独立性:
每一个进程都有自己的空间,在没有经过进程本身允许的
情况下,一个进程不可以直接访问其它的的进程空间
动态性:进程是动态产生,动态消亡的
并发性:任何进程都可以同其它进程一起并发执行
多进程同时工作
对于一个 CPU 而言,它是在多个进程间轮换执行的
线程介绍
线程 (Thread) : 进程可以同时执行多个任务,每个任务就是线程

多线程的意义
随着处理器上的核心数量越来越多,现在大多数计算机都比以往更加擅长并行计算
一个线程,在一个时刻,只能运行在一个处理器核心上


线程:进程中的任务,多线程就是多个任务
多线程的意义:
提高效率
可以同时处理多个任务
Java 开启线程的方式

package com.itheima.thread;
public class ThreadDemo01 {
public static void main(String[] args) {
//创建线程对象
Mythread mythread = new Mythread();
//调用start使用线程
mythread.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程执行的次数"+i);
}
}
}
//编写一个类继承Thread
class Mythread extends Thread{
//重写run方法
@Override
//将线程任务代码写在run方法当中
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("子线程执行的次数"+i);
}
}
}
package com.itheima.thread;
public class ThreadDemo02 {
/*
开启线程的第二种方式 实现Runnable接口
1,编写一个类方法实现runnable
2.重写run方法
3.将线程任务代码 写在run方法当中
4.创建Runnable接口的实现类对象
5.创建线程对象并将Ruuable接口的实现类闯入
6.使用线程对象调用start方法开启线程
*/
public static void main(String[] args) {
MyThread1 mythread = new MyThread1();
Thread t1 = new Thread(mythread);
t1.start();
for (int i = 0; i < 10; i++) {
System.out.println("线程"+i);
}
}
}
class MyThread1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("自己的线程"+i);
}
}
}
package com.itheima.thread;
import java.util.concurrent.Callable;
//编写一个类实现Callable接口
public class Thead5 implements Callable<Integer> {
//重写call方法(此方法存在返回值)
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
return sum;
}
}
线程相关方法
|-----------------------------------|----------------------|
| 方法名称 | 说明 |
| String getName() | 返回此线程的名称 |
| void setName(String name) | 设置线程的名字(构造方法也可以设置名字) |
| static Thread currentThread() | 获取当前线程的对象 |
| static void sleep(long time) | 让线程休眠指定的时间,单位为毫秒 |
| setPriority(int newPriority) | 设置线程的优先级 |
| final int getPriority() | 获取线程的优先级 |
| final void setDaemon(boolean on) | 设置为守护线程 |
|-----------------------------------|----------------------|
| 方法名称 | 说明 |
| String getName() | 返回此线程的名称 |
| void setName(String name) | 设置线程的名字(构造方法也可以设置名字) |
| static Thread currentThread() | 获取当前线程的对象 |
| static void sleep(long time) | 让线程休眠指定的时间,单位为毫秒 |
|------------------------------|----------|
| 方法名称 | 说明 |
| setPriority(int newPriority) | 设置线程的优先级 |
| final int getPriority() | 获取线程的优先级 |
线程调度方式

|-----------------------------------|----------------------|
| 方法名称 | 说明 |
| String getName() | 返回此线程的名称 |
| void setName(String name) | 设置线程的名字(构造方法也可以设置名字) |
| static Thread currentThread() | 获取当前线程的对象 |
| static void sleep(long time) | 让线程休眠指定的时间,单位为毫秒 |
| setPriority(int newPriority) | 设置线程的优先级 |
| final int getPriority() | 获取线程的优先级 |
| final void setDaemon(boolean on) | 设置为守护线程 |
线程安全和同步
需求:
某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票
请设计一个程序模拟该电影院卖票
package com.itheima.test;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest3 {
public static void main(String[] args) {
TicketTask3 ticket = new TicketTask3();
Thread t1 = new Thread(ticket,"窗口A");
Thread t2 = new Thread(ticket,"窗口B");
t1.start();
t2.start();
}
}
class TicketTask3 implements Runnable {
int tickets=1000;
ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try {
lock.lock();
if(tickets==0){
break;
}
System.out.println(Thread.currentThread().getName()+"卖出了第"+tickets+"号票");
tickets--;
lock.unlock();
} finally {
lock.unlock();
}
}
}
}

安全问题出现的条件
是多线程环境
有共享数据
有多条语句操作共享数据
线程安全问题分析


线程同步

线程池介绍
系统创建一个线程的成本是比较高的,因为它涉及到与操作系统交互
当程序中需要创建大量生存期很短暂的线程时,频繁的创建和销毁线程,就会严重浪费系统资源

线程池学习路径

Executors 中提供静态方法来创建线程池
|-----------------------------------------------|------------------|
| 方法 | 介绍 |
| static ExecutorService newCachedThreadPool () | 创建一个默认的线程池 |
| static newFixedThreadPool (int nThreads) | 创建一个指定最多线程数量的线程池 |
自定义线程

线程池拒绝策略
|----------------------------------------|------------------------------------------|
| 策略选项 | 说明 |
| ThreadPoolExecutor.AbortPolicy | 丢弃任务并抛出RejectedExecutionException异常 (默认) |
| ThreadPoolExecutor.DiscardPolicy | 丢弃任务,但是不抛出异常 这是不推荐的做法 |
| ThreadPoolExecutor.DiscardOldestPolicy | 抛弃队列中等待最久的任务 然后把当前任务加入队列中 |
| ThreadPoolExecutor.CallerRunsPolicy | 调用任务的run()方法, 绕过线程池直接执行 |
临时线程什么时候创建?
线程任务数 > 核心线程数 + 任务队列的数量
什么时候会开启拒绝策略
线程任务数 > 最大线程数 + 任务队列的数量
package com.itheima.threadpool;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TheadDemo02 {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
2,
3,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
for (int i = 0; i < 16; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--提交了任务");
}
});
}
}
}
