java多线程
Posted javaxiaobu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程相关的知识,希望对你有一定的参考价值。
多线程就是多个任务同时执行
进程是对操作系统就是多任务执行,每个进程都有自己的代码和数据空间,进程是资源分配的最小单元,一个进程包括至少一个线程
线程多个线程共享代码和数据空间,线程之间切换消耗较小,线程是cpu调度的最小单位
好程序的三高:高可用(数据不会出错)高性能(效率高)高并发(多用户并发)
多线程的创建方式
1继承Thread类 重写run()方法
执行类直接继承Thread类,内部重写run()方法,自身调用start()方法启动多线程
public class Threaddemo01 extends Thread //1继承Thread public static void main(String[] args) Threaddemo01 th=new Threaddemo01(); //3创建对象以及线程 th.start(); //4线程就绪 for(int i=0;i<10;i++) //5主方法的另一线程同步执行 System.out.println("哭");
@Override public void run() //2重写run()方法 for(int i=0;i<100;i++) System.out.println("笑");
|
Thread中
start()方法启动线程
run()方法定义多线程的线程体 通过重写实现不同的代码
run()需要通过start()启动,否则就变为方法的调用,并非多线程
Thread属于lang包
2实现Runnable接口,重写run()方法 --推荐
优点通过类实现接口,能够避免使用extends
缺点是Runnable没有直接的start方法 没有返回值和异常抛出
主要步骤:
1创建多线程类实现接口,并重写run() 注意 :并非是使用多线程的类
2创建多线程类的对象
3开启线程需要创建Thread的静态代理
在静态代理中导入多线程类的对象,通过start()方法启动
new Thread(多线程对象,String).start(); (创建启动同步执行,能够命名线程)
普通创建
public class Threaddemo2 implements Runnable //实现Runnable接口 public static void main(String[] args) Threaddemo2 th=new Threaddemo2(); //创建引用 Thread rh = new Thread(th); //接入静态代理 rh.start(); //代理就绪 for(int i=0;i<10;i++) System.out.println("哭");
@Override public void run() //重写run方法 for(int i=0;i<100;i++) System.out.println("笑");
|
对于只在单个类中使用的多线程类,可以写成成员内部类
对于只在单个方法中使用的多线程类,可以写成局部内部类
简化创建
针对单次并直接使用的多线程体通过匿名类或lambda表达式实现并启动
不再需要另外创建实现Runnable的类
public class Threaddemo3 public static void main(String[] args) new Thread(new Runnable() //匿名类 public void run() for(int i=0;i<100;i++) System.out.println("笑");
).start(); for(int i=0;i<10;i++) System.out.println("哭");
|
new Thread(()-> //直接使用lambda表达式 for(int i=0;i<100;i++)System.out.println("笑");).start(); for(int i=0;i<10;i++) System.out.println("哭");
|
需要练习龟兔赛跑
3实现Callable接口,重写call()方法
优点是可以返回值并抛出异常 属于juc高级多并发处理(了解即可)
1 创建Callable的实现类,在实现类中重写call()方法,在call()中写入多线程体
class 类名 implements Callable<范型> public 返回值类型 call() 多线程的内容 return 返回值 |
2 创建线程
ExecutorService 引用名=Executors. newFixedThreadPool (线程容量);
创建多线程类的对象,获取对象名
Future<返回值类型> 返回值引用名1=引用名.submit(对象名);
Future<返回值类型> 返回值引用名2=引用名.submit(对象名);
引用名.shutdown();
线程状态
新生状态 : new,每个线程都有自己的运行空间
就绪状态 : start(),代表线程具有可运行的能力,在就绪队列中等待cpu调度
运行状态 : cpu把时间片分配给某个线程,这个线程就就行运行状态
阻塞状态 : sleep()..
终止状态 : 执行完毕
注意: 一个线程一旦阻塞状态,阻塞解除进入就绪状态并非继续执行
一旦一个线程以终止,无法恢复,如果创建开启,也是新的线程
终止状态的方法
1)正常执行完毕
2)强制结束 stop(),destroy(),方法已过时,不推荐使用
3)通过标识进行控制--推荐(flag等)
进入就绪状态
1.start()
2.阻塞状态结束
3.yield() 礼让线程,当前线程进入就绪状态
4.线程切换,被切换的线程进入到就绪状态
进入阻塞状态
sleep() 用于将问题放大增加问题发生的可能性 模拟网络延时
wait()
join( thread ) 被插队,等待插队线程执行完毕
IO操作
Thread中的方法
sleep(毫秒) 静态方法
写在多线程中,控制执行线程进入阻塞状态若干时间
用于将增加出现问题的可能性 模拟网络延时
yield() 静态方法
当前线程执行到Thread.yield()时回到就绪排队状态,相当于0秒sleep
join()
插队线程 用于将目标线程插到其他线程的前面
目标线程调用该方法,将调用该方法的代码插入到其他线程的代码中
使得其他线程等待目标线程先执行完成
getStatic()
获取指定线程的线程状态返回一个枚举类
枚举类Thread.State是Thread的内部枚举类,通过该类进行比较
setPriority(int)
设置线程的优先级 优先级包括1-10 默认为5
Thread定义了静态优先级常量
Thread.MAX_PRIORITY=10
Thread.MIN_PRIORITY =1
Thread.NORM_PRIORITY=5
getPriority()
获取线程的优先级
线程安全
多线程同时操作同一份资源,可能出现线程不安全的问题
synchronized同步锁处理方法
锁的范围太大,效率低,锁的范围太小锁不住
1同步方法 效率较低,简单
同步静态方法
同步成员方法
直接在成员方法或成员变量之前加上synchronized修饰符
锁静态方法,锁类的class对象都是锁类,锁住了这个类的所有对象
2同步块
同步块锁的内容就是要线程修改的内容 也相当于钥匙
synchronized(this|类名.calss|资源(成员属性))锁住的代码
多线程执行到同步块时,观察锁对象是否被其他线程调用,若调用则等待
A需要锁的代码在静态方法中时,同步块需要将类全部锁上
Synchronized(类名.class)锁住的代码
锁住的内容包括类的静态内容和所有该类的对象 静态环境中不能使用this
B需要锁的代码在成员方法中,同步块需要将对象锁住
Synchronized(this)锁住的代码
锁住的内容是对象的所有成员属性
C需要锁的内容是属性,可以直接锁属性
Synchronized(属性)锁住的代码
锁一定要锁不变的资源内容,锁的就是地址(自定义类型对象地址)
double check 双重检查 在锁内之前添加if判断 效率高,使得锁的范围小
以上是关于java多线程的主要内容,如果未能解决你的问题,请参考以下文章