javaAPI(多线程)

线程
1、概述
宏观来讲
进程:就是正在运行的程序
线程:就是进程的执行路径,执行单元
2、创建一个线程的两种方式(掌握)
定义一个类继承Thread类

         public class A extends Thread{

          }
          new A().start();

定义一个类实现Runnable接口,并且重写run()方法

        public class A implements Runnable{
               @Override
               public void run(){

               }
          }
          new Thread(new A()).start();

3、线程的随机性原理
多个程序实际是通过CPU在做高效切换实现的

4、线程的声明周期(掌握)
新建 –> 就绪 –> 运行 –>阻塞 –> 死亡

 这里要注意,线程阻塞后就无法执行,回到就绪状态

这里写图片描述

锁,同步代码块,同步方法
1、同步代码块
synchronized(锁对象){
需要被锁的代码//线程只有拿到了锁对象,才能执行这里的代码!!!换言之,这里的代码如果执行了,说明该线程拿到了锁对象,其他线程不能拿到该锁对象
}

 注意
      多个线程必须使用同一个锁对象,要不然锁无效

2、同步方法(掌握)
public synchronized void show(){} //普通方法的锁是this
public static synchronized void show(){} //静态方法的锁是当前类的字节码文件对象 类名.class

3、注意问题
多个线程必须使用同一个锁对象,要不然锁无效
同步代码块锁可以是任意对象
同步方法的锁是this
静态方法的锁是当前类的字节码文件对象 类名.class

4、什么时候用同步代码块,什么时候用同步方法
尽可能用同步代码块
如果一个方法内的所有代码都被同步代码块包住了,那就用同步方法就可以了

5、死锁
死锁原因总结
线程1自身拿着一个锁:A锁,线程2自身拿着一个锁:B锁
当线程1要用B锁,线程B要用A锁的时候就会发生死锁

多个线程操作同一数据的问题(线程键通讯问题)
线程键通讯:
其实就是多个线程同时操作同一个对象

等待唤醒机制
1、前提
两个线程共用一把锁,此时可以调用该锁的wait和notify方法,实现等待唤醒机制

2、IllegalMonitorStateException异常原因及解决办法
如果当前的线程不是此对象锁的所有者,缺调用该对象的notify(),notify(),wait()方法时抛出该异常
换句话说就是当前线程中的同步代码块的锁 和 调用这三个方法的锁对象不一致就会报错,例如
synchronized(Student.class){
Object.class.notify();
}

 注意 必须有线程现在自食用Object.class锁

3、sleep和wait的区别
wait:是Object类的方法,可以不用传递参数,释放锁对象
sleep:是Thread类的静态方法,需要传递参数

案例:共享数据(学生类)

//共享数据(学生类)
public class Student {
       public String name;
       public int age;

       public boolean flag = false;

       @Override
       public String toString() {
              return "Student [name=" + name + ", age=" + age + "]";
       }
}
//线程1:负责修改共享数据
public class SetThread extends Thread {
       private Student stu;

       public SetThread(Student stu) {
              this.stu = stu;
       }

       @Override
       public void run() {
              int i = 0;
              while (true) {

                     synchronized (stu) {
                            if(stu.flag){
                                   try {
                                          stu.wait();
                                   } catch (InterruptedException e) {
                                          e.printStackTrace();
                                   }
                            }
                            if (i % 2 == 0) {// 执行%2操作,是为了写入不同的数据,测试在写入过程中,是否影响另一个线程的读取操作
                                   stu.name = "张三";
                                   stu.age = 13;
                            } else {
                                   stu.name = "李四";
                                   stu.age = 14;
                            }
                            i++;
                            stu.flag = true;
                            stu.notify();

                     }
              }

       }
}
//线程2:负责获取共享数据信息
public class GetThread extends Thread {
       private Student stu;
       public GetThread(Student stu){
              this.stu = stu;
       }
       @Override
       public void run() {
              while(true){
                     synchronized (stu) {
                            if(!stu.flag){
                                   try {
                                          stu.wait();
                                   } catch (InterruptedException e) {
                                          e.printStackTrace();
                                   }
                            }
                            System.out.println(stu);
                            stu.flag = false;
                            stu.notify();
                     }
              }
       }
}
//测试 
public class Test {
       public static void main(String[] args) {
              //创建共享数据
              Student stu = new Student();
              //创建两个线程,并且让这两个线程同时操作这个共享数据
              GetThread get = new GetThread(stu);
              SetThread set = new SetThread(stu);

              get.start();
              set.start();
       }
}

线程的优先级(Thread类中)
1、线程优先级级别
线程默认优先级是5。范围是1-10
Thread.MAX_PRIORITY //10
Thread.MIN_PRIORITY //1
Thread.NORM_PRIORITY //5

2、方法
public final int getPriority():获取线程优先级
public final void setPriority(int newPriority):更改线程的优先级

3、注意
优先级可以在一定的程度上,让线程获较多的执行机会

4、举例
MyThread t = new MyThread();
System.out.println(t.getPriority());
t.setPriority(Thread.MAX_PRIORITY);

暂停线程(Thread类中)
1、概述
暂停当前正在执行的线程,让其他线程执行

2、成员方法
public static void yield():暂停当前正在执行的线程对象,并执行其他线程。

3、注意
是为了让线程更和谐一些的运行,但是你不要依赖这个方法保证,如果要真正的实现数据依次输出,请使用等待唤醒机制

加入线程(Thread类中)
1、概念
如果调用一个线程的join方法,那么其他线程必须等待该线程执行完毕后才能执行

2、成员方法
public final void join():等待该线程终止

 线程启动后调用该方法

守护线程(Thread类中)

1、成员方法
public final void setDaemon(boolean on):设置线程为守护线程,一旦前台(主线程),结束,守护线程就结束了

2、注意
main方法就本身是一个线程,我们在main方法里创建线程,并且设置线程为守护线程后,main方法结束后,守护线程就自动结束了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值