Java关键字




atomic
1、包括AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference<T>。
2、多线程并发操作同一资源时,保证操作的原子性,即所有操作步骤要么都成功要么都失败。
3、采用Lock-free算法,比synchronize开销小、速度快。Lock-free基于CAS原子操作。
4、CAS即CPU乐观锁,Compare and Swap。而synchronize使用CPU悲观锁,即独占锁,其他线程阻塞等待,而后CPU上下文切换,低效。
5、CAS:1)复制原始值到比较量2)算出新值3)比较当前原始值和比较量,相等则替换成新值。
6、Lock-free存在ABA问题。A读,B改,C改回,A以为没改其实改了。
7、原子操作,指一个CPU时钟内就可以完成的操作而不会被其他操作干扰。

volatile
1、用于多线程并发时变量的可见性,即在一个线程的工作内存中修改了该变量的值,该变量的值立即能回显到主内存中,从而保证所有线程看到这个变量的值是一致的。
2、但仍然存在并发问题,即不能保证对该变量的操作的原子性,尤其对该变量的写操作依赖于该变量自身。
3、总结:使变量的值在发生改变的时候能够尽快的让其他线程知道。
4、原因:编译器为了加快程序的运行速度,对一些变量的写操作会现在寄存器或者是CPU缓存上进行,最后才写入内存,而这个过程,变量的新值对其他线程是不可见的,而volatile的作用是是它修饰的变量的读写操作都必须在内存中进行。

synchronize
1、使用方便,性能低效。是Lock简化版,性能不如Lock。Lock采用乐观锁。
2、ReentrantLock+一个Condition。而Lock可以对应多个Condition。

volatile与synchronize
1、volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,而synchronize则是锁定当前变量,只有当前线程可以访问该变量,其他线程阻塞。
2、volatile仅能使用在变量级别,而synchronize则可以使用在变量、方法。
3、volatile仅能实现变量的修改可见性,但不具备原子性,而synchronize则可以保证变量的修改可见性和原子性。
4、volatile不会造成线程阻塞,而synchronize可能会造成线程阻塞。
5、volatile标记的变量不会被编译器优化,而synchronize标记的变量可以被编译器优化。

volatiel另解
1、volatile修饰的成员变量在每次被线程访问的时候,都强迫从共享内存中重新读取该成员变量的值,而且当成员变量的值发生变化的时候,强迫将变化的值重新写回共享内存,这样两个不同的线程在访问同一个共享变量的值的时候,始终看到的是同一个值。
2、Java语言规范指出:为了获取最佳的运行速度,允许线程保留共享变量的副本,当这个线程进入或者离开同步代码块时,才与共享变量进行比对,如果有变化再更新共享成员变量。这样当多个线程同时访问同一个共享变量的时候,可能会存在值不同步的现象。而volatile的作用就是告诉jvm:对于这个成员变量不能保存它的副本,要直接与共享成员变量交互。
3、使用volatile将使得jvm优化失去作用,导致效率低下,所以在必要时使用。

lock
synchronized原语和ReentrantLock在一般情况下没有什么区别,但是在非常复杂的同步应用中,请考虑使用ReentrantLock,特别是遇到下面2种需求的时候。
1、某个线程在等待一个锁的控制权的这段时间需要中断 。
2、需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程 。
3、ReentrantLock这个类还提供了2种竞争锁的机制:公平锁和非公平锁。这2种机制的意思从字面上也能了解个大概:即对于多线程来说,公平锁会依赖线程进来的顺序,后进来的线程后获得锁。而非公平锁的意思就是后进来的锁也可以和前边等待锁的线程同时竞争锁资源。对于效率来讲,当然是非公平锁效率更高,因为公平锁还要判断是不是线程队列的第一个才会让线程获得锁。

threadlocal
1、atomic、volatile、synchronize都是从线程外来保证变量的一致性,使得多线程访问的变量具有一致性,更好的体现出资源的共享。
2、变量的一致性,即别的线程对变量的操作结果,我必须获取到,从而保证一致性。
3、threadlocal并不解决上述资源共享的问题。因为它不解决操作的一致性问题,从而无法保证变量的一致性问题。
4、threadlocal拷贝变量副本提供到线程内部,从而每个线程都使用自己的变量副本,相互不影响。
5、threadlocal建议声明为private static,否则有内存泄漏问题,因为map key为弱引用,gc时会回收,导致key为null,value强应用,回收不了,泄漏。
6、threadlocal在线程使用完毕后,应该手动remove,移除该值,防止内存泄漏。

并发
1、volatile具有可见性,但不具有操作原子性,而synchronize资源消耗大,但可以保证操作原子性,从而保证变量一致性。最好二者结合使用。
2、synchronize,同步机制采用时间换空间的方式,访问串行化、对象共享化。同步即提供一份变量,让所有线程访问。
3、atomic,原子操作指令+lock-free,实现非阻塞式并发。
4、volatile为多线程资源共享问题解决了部分需求,在非依赖自身的操作的情况下,对变量的改变将对任何线程都可见。
5、threadlocal并不解决多线程资源共享问题,而是提供线程内的局部变量,省去参数传递的麻烦,以空间换时间:访问并行化、对象独享化。
6、threadlocal为每个线程都提供一份独有的变量副本,互不影响。

参数值传递
Java参数传递采用值传递,基本类型的变量,相当于将变量进行了拷贝,变量在方法内的改变不会影响方法外的值。
但参数为复核类型时,传地址,值可改。

内部类
1.分为:成员内部类、局部内部类、匿名内部类、静态内部类。
2.内部类可以访问外部类的所有属性和方法,外部类必须先new出内部类实例后再访问变量和方法。
3.必须先创建外部类实例后再创建内部类实例。
4.内部类可以用private、protected、默认、public修饰,普通类不行(只能用public或默认),默认即同包访问。
5.局部内部类定义在方法或作用域内,相当于变量,所以不能用public、private、protected、static修饰。
6.匿名内部类常用于事件监听器。没有构造器。常用于接口回调。
7.静态内部类,即静态的内部类。

接口变量
接口变量隐性为public static final,即静态、赋初值且不能改。

接口abstract
接口方法隐性为abstract。

final
1.修饰类,类不能被继承,通常用于叶子类,或安全考虑;所有方法隐性为final方法,不能覆盖;变量可根据需要标注final。
2.修饰方法,方法不能被覆盖;早期Java将final方法转为内嵌调用,但会使调用主体方法变得庞大,谨慎使用;private方法隐性 为final方法。
3.修饰变量:
     1).变量为基本类型,则初始化后不能修改。
     2).变量为复合类型,则引用不能修改,即不能再指向其他对象,但值可改。

==和equals
1.基本类型时,相同,比值。
2.复合类型(包装类)时,==比地址,equals比值。
3.自定义类时,==比地址,equals覆盖时比值,equals未覆盖时比地址。

i++和++i
1.单独执行没有区别。
2.放在语句中,则:++在后则后运算先执行,++在前则先运算后执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值