• 第一种创建线程的方式 继承Thread类

1.定义类继承Thread类
2.重写Thread类的Run方法(线程任务)
3.开启线程
创建子类对象
调用Thread类的start方法
调用run方法和调用start方法的区别
调用run方法程序还是单线程的程序
调用start方法 jvm会在子类线程中自动调用run方法
程序就是一个多线程的程序了
为什么开启线程要继承Thread类?
因为Thread类是线程类,具备线程应该有的属性和功能
继承Thread类 就也是线程类,可以直接使用线程的功能
那为什么不直接创建Thread类的对象 开启线程?
Thread t = new Thread();
t.run();
这样虽然也能创建线程,但是在线程中执行的是Thread类的自己的run方法,这个run方法中的
内容 并不是我们想要的,所以我们继承Thread重写run方法 这样调用run方法
就是我们重写后的run方法了

Thread类方法
String getName()获取线程名称

static Thread curretThread()获取当前线程对象

String getName()获取线程名称

第二种创建线程的方式 实现Runnable接口

  1. 定义实现类 实现 Runnable接口
  2. 重写run方法 线程任务
  3. 开启线程

    • 创建实现类对象
    • 创建Thread类型对象 传入实现类对象

      1. public Thread(Runnable r)
    • 调用Thread类的start方法

  • 为什么有了继承Thead的方式 还要有实现Runnable接口的方式?
  1. 避免了单继承局限性 如果一个类已经有了父类 第一种方式不能开启线程了 只能使用第二种方式
  2. 线程对象 和 线程任务 解耦合 第一种方式 线程对象和线程任务是耦合在一起的

    第二种方式线程任务和线程对象是分开的

  3. 更适合多个线程共享一个资源

-匿名内部类的方式开启线程
格式
new 父类/接口(){

};
Thread类的静态方法
static void sleep(long time)当前执行到这个方法的线程 进入到睡眠 睡眠time毫秒后 继续执行

线程的优先级
void setPriority(int field)设置优先级 优先级 1-10 5是默认 1最低 10最高
静态常量
public static final int MIN_PRIORITY//最低优先级
public static final int NORM_PRIORITY//默认优先级
public static final int MAX_PRIORITY//最大优先级

Thread类
  join方法 让当前线程等待 调用方法的线程插队 调用方法的线程执行完毕 当前线程继续执行
  当前线程指的是 Thread.currentThread()

线程终止

Thread类
  void stop()停止线程 此方法已经过时了 不推荐使用
  void interrupt()中断线程
  boolean isInterrupted()判断线程是否中断 如果是则返回ture

线程安全

-线程不安全
当多条线程 同时访问一个资源 就有可能出现数据错误 线程不安全
-如何解决

  1. 线程同步
  2. lock锁 JDK1.5

-线程同步

  • 同步代码块

    • synchronized(任意对象){

                }
      
  • 同步方法

    • 在方法的返回值类型之前 加上关键字 synchronized

-同步方法有锁吗?有锁!锁是谁?this
-同步方法可以是静态的吗?可以是静态的!
-但是此时锁还是this吗?不是
锁是谁?当前类名.class

java.util.concurrent.locks.Lock 接口

方法
void lock()获取锁
void unlock()释放锁
实现类
Reentrantlock();
  构造方法
    public ReentrantLock();

wait

  • 方法

    • void wait()在其他线程调用此对象的 notify()方法或 notifyAll()方法前

        导致当前线程等待
      
    • void wait(long timeout)线程等待 等待time毫秒之前 如果有人唤醒 则醒来获取

          锁继续执行 如果没有被唤醒 当time时间到 会自动醒来 获取后继续执行
      
    • void notify()唤醒在此对象监视器上等待的单个线程

    • void notifyAll()唤醒在此对象监视器上等待

注意:wait和notify方法必须由对象监视器调用
必须在同步中使用
当线程遇到wait方法 必须由这个对象监视器用notify方法才能唤醒
如果对象监视器上 等待了多条线程 notify方法只是唤醒其中一个
如果想全程唤醒 调用notifyAll方法

wait和sleep的区别?
sleep是Thread类的静态方法 既可以在同步外使用 也可以在同步内使用
如果在同步中使用 线程sleep的时候 并不会释放锁
wait是Object类的方法 只能在同步内 被锁对象调用 当线程wait时 会释放掉锁对象
必须有人唤醒 唤醒后需要重新获取后才能执行