线程
1.进程是资源分配最小单位,线程是最小执行单位
2.一个进程可以有多个线程
3.线程共享进程资源
Thread类
//一个简单的线程例子
//1.创建类extends Thread 然后重写它的run方法,run()方法里可以是我们的实现逻辑
//2.实例化我们创建的线程类,start()启动它
public class Demo{
public static void main(String[] args){
Thread a=new MyThreadA();
a.start();
Thread b=new MyThreadA();
b.start();
}
}
class MyThreadA extends Thread{
@Override
public void run(){
for(int i=0;i<=100;i++){
...
try{
Thread.sleep();//我们也可以让线程休眠
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
1.我们可以创建多个线程,至于最后谁先执行实际上控制不了,它们几乎同时运行
Runnable接口
为Thread只能继承一个Thread,使用Runnable接口就可以 继承其他的
//1.implements Runnable接口 2.记得将对象作为参数传入线程里
public class Demo{
public static void main(String[] args){
MyRunnableA myRunnableA=new MyRunnableA();
Thread a=new Thread(myRunnableA);//2.将对象传入
a.start();
}
}
//1.implements Runnable接口
class MyRunnableA extends 其他类 implements Runnable{
@Override
public void run(){
for(int i=0;i<=100;i++){
...
try{
Thread.sleep();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
线程生命周期
线程加入
//线程对象.join();----等待该线程终止,原线程才能继续运行
//线程对象.join(最久等多少毫秒);----等多少毫秒后启动线程
class A extends Thread{
@Override
public void run(){
Thread B=new Thread;
B.start();
B.join();//启动A线程之前会先等B线程结束
}
}
线程中断
//线程对象.interrupt();
//可能发生异常InterruptedException
class A extends Thread{
@Override
public void run(){
try{
Thread B=new Thread;
B.start();
if(...){
B.interrupt();//线程中断
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
线程优先级
线程1-10级,级别越高越先执行
如果同级别,谁先就先执行谁
线程优先级设置
理论上是执行顺序,实际上cpu执行我们无法预测,即使设置效果不明显
//设置优先级setPriority(优先级别如下),通常启动前设置一下
// Thread.MAX_PRIORITY=10
// Thread.MIN_PRIORITY=1
// Thread.NORM_PRIORITY=5
public class Demo{
public static void main(String[] args){
Thread a=new Thread();
a.setPriority(3);
a.start();
Thread b=new Thread();
b.setPriority(Thread.MAX_PRIORITY);
b.start();
}
}
线程同步
同步----同步操作没有结束之前,后面的代码是无法执行的。
异步----异步操作没有结束之前,后面的代码是可以执行的。
补充知识点:Promise–使用同步方式写异步,因为异步操作可能出现回调地狱
同步为什么使用synchronized?----因为同一进程下,不同线程共享同一资源,可能发生线程资源抢夺,脏数据,死锁;如果我们使用锁,一个一个获取资源,就能解决资源抢夺问题
public class Demo{
public static void main(String[] args){
Thread a=new MyThreadA();
Thread b=new MyThreadA();
Thread c=new MyThreadA();
Thread d=new MyThreadA();
a.start();
b.start();
c.start();
d.start();
}
}
//synchronized我们可以在同步代码块/同步方法上添加锁
//同步代码块synchronized(需要锁的对象){}
class MyThreadA extends Thread{
@Override
public void run(){
synchronized(this){
...需要处理的事情
}
}
}
//同步方法synchronized void 方法(){}
class MyThreadA extends Thread{
@Override
public void run(){
sell();
}
//在需要的方法上加锁
private synchroized void sell(){
...需要处理的事情
}
}
线程暂停与恢复
wait()等待
notify()唤醒
通常将等待和唤醒分别放在不同方法里,根据需求不同需求调用不同方法
//使用:暂停标志+synchroized+wait/notify
@Override
public void run(){
synchronized(this){
while(暂停标志){
wait();
}
}
}
//注意使用到synchroized
public synchroized void toSuspend(){
暂停标志=true;
}
public synchroized void toResume(){
暂停标志=false;
notify();
}