单线程
多线程
1.使用继承Thread类实现多线程
线程对象调start方法时,自动调用重写的run方法;主线程和子线程谁先谁后执行是不一定的
注意事项
2.实现Runnable接口,以此实现多线程
用一个任务类实现Runnable接口,并重写run方法。创建任务类对象不能直接调用start方法,要创建Thread类对象,并将任务类对象放进Thread类对象的构造器中再调用start方法
2.匿名内部类
直接创建匿名内部类的对象
简化
3.
线程结束应该返回的数据类型要写在<>中
该线程执行结束返回的结果是String类型,在泛型那写上String;创建MyCallable对象时一定要用多态写法,用父类的引用;任务对象有一个构造器可以接收Callable对象;f1还能通过get()方法获取线程结束返回的结果
Thread方法和构造器
用类Thread直接调用currentThread方法可以得到一个线程对象,哪个线程执行它,它就获得哪个线程对象,当前是main来执行
输出结果
在方法中加入Thread调用currentThread方法,代表当前正在执行的线程对象,用该对象来调用getname即可获取当前线程的名字
setname()可以在每个线程启动前为线程设置名字
采用有参构造器在创建线程对象时设置名字,在子类中创建一个构造器,再用super调用父类的构造器
sleep方法,慢一点
join方法,先让当前线程执行完再执行下一个线程
银行同时取钱
在线程类中定义一个账户类的对象,对象用构造器传进来后用this.接收,这样就能得到一个Account的对象
线程启动后会调用线程中的run方法,再根据对象调用drawMoney方法。两个线程同时启动,此时会出现冲突
线程同步
加锁
同步代码块(同步锁)
对访问共享资源的核心代码块上锁,上锁时要传入一个一样的对象,用String类型的字符串就可以,因为这个对象在常量池中,只有一份
用this作为锁,当小明小红来到时this是acc对象;当小黑小白来到时,this是acc1对象
对于静态方法用类名.class作为锁
锁的选择
同步方法
给方法上锁
Lock锁
创建lock锁,用dinally修饰,不能二次赋值,每个账户对象共用一个lock锁
要进行加锁和解锁
最好用try-catch-finally,这样可以保证能解锁
线程池
参数六负责创建核心线程和临时线程
这两个代表临时线程存活8秒,TimeUnit是枚举类
线程池:1.用链表实现,可以有无限个线程在队列中
2.任务队列缓存线程,自己标明能缓存多少个线程,此时能缓存4个
获取默认线程池工程
重点
处理runnable任务方法
execute方法,将Runnable对象传进来,自动执行Runnable任务
输出结果,会复用三个核心线程处理
关闭线程池的方法
此时有五个线程,其中3个在忙,4个进入线程池
此时3个在忙,任务队列中4个线程也满,那么剩下的一个会进入临时线程
拒绝任务策略
处理callable
相比处理runnable,处理calable执行任务时,传了calable对象后会返回一个未来任务对象,该对象是Future类的子类,用Future来接收,泛型<>要和calable中返回的类型一样,用get获取返回的结果
实现线程池的第二种方法
并发和并行
并发和并行同时进行
线程的状态
线程进入sleep状态前就得到锁对象,进入sleep时不会释放锁,睡眠时间到立刻执行
wait前不会得到锁,wait会释放锁