Java多线程 多线程是什么意思( 三 )


2)volatile只能用于修饰变量 , 而synchronized可以修饰方法 , 以及代码块 。(volatile是线程同步的轻量级实现 , 所以volatile性能比synchronized要好 , 并且随着JDK新版本的发布 , sychronized关键字在执行上得到很大的提升 , 在开发中使用synchronized关键字的比率还是比较大);
3)多线程访问volatile不会发生阻塞 , 而sychronized会出现阻塞;
4)volatile能保证变量在多个线程之间的可见性 , 但不能保证原子性;而sychronized可以保证原子性 , 也可以间接保证可见性 , 因为它会将私有内存和公有内存中的数据做同步 。
线程安全包含原子性和可见性两个方面 。
对于用volatile修饰的变量 , JVM虚拟机只是保证从主内存加载到线程工作内存的值是最新的 。
一句话说明volatile的作用:实现变量在多个线程之间的可见性 。
synchronized和lock区别:
1)Lock是一个接口 , 而synchronized是Java中的关键字 , synchronized是内置的语言实现;
2)synchronized在发生异常时 , 会自动释放线程占有的锁 , 因此不会导致死锁现象发生;而Lock在发生异常时 , 如果没有主动通过unLock()去释放锁 , 则很可能造成死锁现象 , 因此使用Lock时需要在finally块中释放锁;
【Java多线程 多线程是什么意思】3)Lock可以让等待锁的线程响应中断 , 而synchronized却不行 , 使用synchronized时 , 等待的线程会一直等待下去 , 不能够响应中断;
4)通过Lock可以知道有没有成功获取锁 , 而synchronized却无法办到 。
5)Lock可以提高多个线程进行读操作的效率(读写锁) 。
3 使用线程安全的简单用例
3.1 同步代码块
public class ThreadSafeProblem {public static void main(String[] args) {Consumer abc = new Consumer();// 注意要使用同一个abc变量作为thread的参数 , // 如果你使用了两个Consumer对象 , 那么就不会共享ticket了 , 就自然不会出现线程安全问题new Thread(abc,"窗口1").start();new Thread(abc,"窗口2").start();}}class Consumer implements Runnable{private int ticket = 100;@Overridepublic void run() {while (ticket > 0) {synchronized (Consumer.class) {if (ticket > 0) {System.out.println(Thread.currentThread().getName() + "售卖第" + (100-ticket+1) + "张票");ticket--;}}}}}


3.2 Lock锁是需要手动去加锁和释放
/* * 使用ReentrantLock类实现同步 * */class MyReenrantLock implements Runnable{//向上转型private Lock lock = new ReentrantLock();public void run() {//上锁lock.lock();for(int i = 0; i < 5; i++) {System.out.println("当前线程名: "+ Thread.currentThread().getName()+" ,i = "+i);}//释放锁lock.unlock();}}public class MyLock {public static void main(String[] args) {MyReenrantLock myReenrantLock =new MyReenrantLock();Thread thread1 = new Thread(myReenrantLock);Thread thread2 = new Thread(myReenrantLock);Thread thread3 = new Thread(myReenrantLock);thread1.start();thread2.start();thread3.start();}}


3.3 volatile关键字
public class Singleton3 {private static volatile Singleton3 instance = null;private Singleton3() {}public static Singleton3 getInstance() {if (instance == null) {synchronized(Singleton3.class) {if (instance == null)instance = new Singleton3();}}return instance;}}




4 常见的问题研究1. 什么叫线程安全?servlet是线程安全吗?2. 同步有几种实现方法?3.volatile有什么用?能否用一句话说明下volatile的应用场景?4. 请说明下java的内存模型及其工作流程 。5. 何解决多线程之间线程安全问题?6.为什么会有线程安全问题?7.多线程死锁?8.说一说自己对于 synchronized 关键字的了解9. 怎么使用 synchronized 关键字10. 讲一下 synchronized 关键字的底层原理11.说说 JDK1.6 之后的synchronized 关键字底层做了哪些优化 , 可以详细介绍一下这些优化吗12. 谈谈synchronized和ReenTrantLock 的区别13. synchronized 关键字和 volatile 关键字的区别
常见出现的问题会在后面的文章讨论 , 想一起讨论学习的朋友可以点下关注 , 会持续更新 , 文章有帮助的话可以收藏 , 转发 , 有什么补充可以在下面评论 , 谢谢!

二、什么是多线程举个例子 , 你要做饭 , 你要做的饭是米饭和一个炒菜 。
如果是单线程 , 那么你可以如下做:
第一种方法:先炒菜 , 然后开始蒸米饭;