多线程优点:
提高程序的处理能力,效率提高了
提高cpu利用率
大任务的拆分
杀毒软件
垃圾清理1分钟
病毒查杀.....
多线程缺点:
线程也是需要占用内存资源和cpu资源(小意思 可以提升硬件设备)
多个线程对同一个共享的资源进行访问,出现线程安全的问题
龟兔赛跑中的flag就是共享资源
如何解决多个线程访问同一个共享资源
synchronize修饰代码块
同步对象:对多个线程对应的对象必须是同一个,用来记录有没有线程进入到同步代码块中的,在对象的对象头中有一块空间用来记录有没有对象进入同步代码块,同步对象可以是java中任何类的对象
synchronize(同步对象){
同步代码块
}
synchronize如果修饰的是静态方法,那么同步对象就是当前类的Class对象;
当前类的Class对象:一个类加载到内存后,会为这个类创建一个唯一的Class类对象
synchronize如果修饰的是非静态方法,那么同步对象就是this
修饰代码块
同步对象要求:
多个线程用到同一个对象
可以是java中任何类的对象.
作用:用来记录有没有线程进入到同步代码快中
//同步代码快,一次只允许一个线程进入
修饰方法:
1.锁不需要我们提供,会默认提供锁的方法
2.synchronize如果修饰的是非静态方法,锁对象就是this
synchronize如果修饰的是静态方法,锁对象就是类的Class对象
一个类只有一个Class对象.
加锁方式2:
使用jdk中提供的ReentrantLock类实现加锁
ReentrantLock只能对某一段代码块进行加锁
synchronize和ReentrantLock的区别
相同:都加锁
不同:
1.s:是一个关键字,r是一个类
2.s修饰代码块和方法,r只能修饰代码块
3.s可以隐式的加锁和释放锁,运行过程中如出现了异常可以自动释放
r需要手动的添加锁和释放锁,建议在finally代码块里释放锁
线程通讯涉及的三个方法 :
wait(); 让线程等待,自动释放锁,必须要其他的线程唤醒
notify(); 唤醒等待中的线程(调用了wait方法的线程),如果有多个等待,唤醒优先级高的
notifyAll();
这三个方法都是object类中定义的方法
这三个方法必须在同步代码块中使用
这三个方法必须为锁的对象调用
线程间的通信(在同步代码快的基础上,使用wait,notify对线程进行控制)
创建线程方式3:实现callable接口
相比run()方法,可以有返回值
方法可以抛出异常
支持泛型的返回值
需要借助FutureTask类,获取返回结果