多线程
同时运行了多个线程,用来完成不同的工作
多个线程交替CPU资源
好处:
充分利用CPU的资源
简化编程模型
带来良好的用户体验
进程和线程的区别
进程
应用程序的执行实例-》进程《-有独立的内存空间和系统资源
线程
CPU调度和分派的基本单位-》线程《-进程中执行运算的最小单位,可完成一个独立的顺序控制流程
主线程
java.lang.Tread类支持多线程
main()方法即主线程入口
实现Runnable接口创建线程
- 自定义Thread类末尾要加Thread
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动多线程
在main方法里直接调用run()方法只执行一个线程main(单线程),一个执行完在执行一个。
start()方法是多线程交替执行(CPU分配时间片)
继承Thread类
- 编写简单,可直接操作线程
- 是用于单根继承
实现Runnable接口
- 避免单继承局限性
- 便于共享资源
线程的状态和线程的调度
线程的五个状态
创建、就绪、阻塞、运行、死亡
线程调度的方法
setPriority(int grade) 优先级调整
// 获得当前线程名
Thread.currentThread().getName();
// 线程优先级最高
setPriority(Thread.MAX_PRIORITY);
// 线程优先级最低
setPriority(Thread.MIN_PRIORITY);
sleep(long millis) 线程休眠
Thread.sleep(1000); // 休眠1000毫秒
join() 线程强制执行使该线程先执行完毕
yield()优先级默认5 由1-10表示让线程暂时书面指定时常,线程进入阻塞状态
public static void main(String[] args) {
System.out.println("*************线程强制执行*************");
// 1.创建线程对象
Thread temp = new Thread(new MyRunnable3(),"temp");
temp.start();
for (int i = 0; i < 20; i++) {
// 当主线程执行到i==5时,暂停主线程,让子线程temp执行完毕之后,主线程再执行
if (i==5) {
try {
temp.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dSystem.out.println(Thread.currentThread().getName()+"运行:"+i);
}
线程的礼让yield();暂停当前线程,允许其他具有相同优先级的线程获得运行的机会。
该线程处于就绪状态,不转为阻塞状态
该礼让不一定会实现
线程的同步
使用synchronized修饰的方法控制对类成员变量的访问
可以放在访问修饰符前面或后面
synchronized就是为当前线程声明一个锁
使用synchronized关键字修饰的代码块
synchronized (this) {
while(true) {
if (count <= 0) {
break;
}
// 1.修改数据(剩余票数、抢到第几张票)
count--;
num++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 2.显示信息,反馈用户抢到第几张票
System.out.println(Thread.currentThread().getName()+"抢到第"+num+"张票,"+"剩余第"+count+"张票");
}
多个并发线程访问同一资源的同步代码块时
- 同一时刻只能有一个线程进入synchronized(this)同步代码块
- 当一个线程访问一个synchronized(this)同步代码块时,其他synchronized(this)同步代码块同样被锁定
- 当一个线程访问一个synchronized(this)同步代码块时,其他线程可以访问非synchronized(this)同步代码
StringBuffer是同步的,StringBuilder非同步
HashTable是同步的,HashMap是非同步的
一般同步的用于多线程,非同步用于单线程
死锁
死锁-两个线程都在等待对方先完成,造成程序的停滞
死锁条件
-
两个或两个以上的线程在活动
-
某个线程拿到一个锁以后,还想拿第二个锁,造成所得嵌套
线程池
executors工具类
缓存线程池
public class ThreedPool {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
// 在线程池中执行10个任务
for (int i = 0; i < 10; i++) {
es.execute(new MyRunnable(i));
}
}
}
class MyRunnable implements Runnable{
int num;
public MyRunnable(int num) {
super();
this.num = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+":"+num);
}
}
单线程池
public class ThreedPool {
public static void main(String[] args) {
ExecutorService es = Executors.newSingleThreadExecutor();
// 在单线程池中执行任务
for (int i = 0; i < 10; i++) {
es.execute(new MyRunnable(i));
}
}
}
class MyRunnable implements Runnable{
int num;
public MyRunnable(int num) {
super();
this.num = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+":"+num);
}
}
固定线程池
public class ThreedPool2 {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
// 在线程池中执行3个任务
for (int i = 0; i < 10; i++) {
fixedThreadPool.execute(new MyRunnable1(i));
}
}
}
class MyRunnable1 implements Runnable{
int num;
public MyRunnable1(int num) {
super();
this.num = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+":"+num);
}
}
定时执行任务线程
public class ThreedPool3 {
public static void main(String[] args) {
ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
System.out.println("**********开始执行************");
ses.scheduleAtFixedRate(new MyRunnable2(), 5, 2, TimeUnit.SECONDS);
}
}
class MyRunnable2 implements Runnable{
int num;
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"延时5s执行,每2s执行一次!");
}
}
自定义线程
ublic class ThreadPool4 {
public static void main(String[] args) {
ThreadPoolExecutor tpe = new ThreadPoolExecutor(5,7,300,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(4));
for (int i = 1; i <= 12; i++) {
tpe.execute(new MyRunnable4(i));
System.out.println("线程池中的线程数:"+tpe.getPoolSize()+"队列中等待执行的线程数:"+tpe.getQueue().size()
+"已经执行完的线程数:"+tpe.getCompletedTaskCount());
}
tpe.shutdown();
}
}
class MyRunnable4 implements Runnable{
int num;
public MyRunnable4(int num) {
super();
this.num = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("正在执行任务"+num);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("任务"+num+"执行完毕!");
}
}
序号 | 名称 | 类型 | 含义 |
---|---|---|---|
1 | corePoolSize | int | 核心线程池大小 |
2 | maximumPoolSize | int | 最大线程池大小 |
3 | keepAliveTime | long | 线程最大空闲时间 |
4 | unit | TimeUnit | 时间单位 |
5 | workQueue | BlockingQueue | 线程等待队列 |
6 | threadFactory | ThreadFactory | 线程创建工厂 |
7 | handler | RejectedExecutionHandler | 拒绝策略 |