Java多线程理解
来源:互联网 发布:经典算法面试题及答案 编辑:程序博客网 时间:2024/06/14 02:15
两个概念
并行
并行指的是一台机器多个cpu处理,是真正意义上的同时处理。
并发
并发指的是单cpu环境下,为了提高cpu使用效率,将cpu资源按时间片划分,交由不同的线程任务轮流执行,微观上讲,多个线程任务间,并不是同时处理的。
对于线程,举Java中两种实现方式
1.继承Thread类
public class MyThread extends Thread { public static void main(String [] args){ MyThread thread = new MyThread(); thread.start(); } @Override public void run() { System.out.println("thread running"); }}
调用方法如main()方法中一样,通过线程实例的start方法调用
2.实现Runnable接口
public class MyThread implements Runnable{ public static void main(String [] args){ Thread thread = new Thread(new MyThread()); thread.start(); } @Override public void run() { System.out.println("thread running"); }}
调用方法如main()方法中,新建一个Thread实例,并在构造时传入实现Runnable接口的类实例,然后通过Thread实例调用其start()方法
两种方法都需要重写run()方法,不难推出,Thread类实际上也是一个Runnable接口实现类
线程状态转换
不多说,只谈一点
在调用线程start()方法后,线程并不是立即执行,而是进入可运行状态,与其他线程竞争cpu资源,到cpu执行时才是真正运行
线程同步问题
这里简单地谈下我对线程同步的理解,之后有时间再详细深入地总结。
在我看来,多线程同步的目的,归根到底是对线程间共享资源或共享数据的保护。
一个简单的例子,在秒杀活动中,多用户在极短时间内同时发起抢购。
在后台是多个线程并发的,多个不同线程间会涉及一个重要的公共数据库存量n
假设同时有A,B两条线程发起抢购
理想情况:A和B会使库存量-2,得到结果 n=98
然而由于Java线程特性,结果并非一定如此,由于线程调度的随机性,可能会出现下述的这种情况。
数据异常情况:A先到达,读取n的值为100,然后cpu轮到b,b也读取n的值为100,再轮到a,a行n > = n-1,此时n为99,此时cpu运行b,b执行n = n -1=99,此时a和b都被执行,结果应该是98,但是计> > 算结果确是99或许还会有其他数据异常状况,这会使我们得程序不安全,无法投入使用。
其实到这里的故事大家都耳朵出老茧,但是却没有将它和之后的故事建立联系,这也是导致了我之前一直对线程同步的问题懵的原因
按照我们的理想情况,不同线程对共享数据操作时,必须是由某一线程独占的,其余线程需要等之前的线程执行完成之后才能正确
没错,说到底为了结果的准确,在对线程间的公共数据和资源操作时应该是由某一个线程独占的这样,线程同步的问题,就转化为如何让某线程独占数据和资源,其实微观上看,在线程独占数据和资源时也恰恰是他独占CPU操作数据和资源的时候。
或者可以说,线程同步的问题就是如何让多条线程在操作共享资源的时候独占 cpu ,从而达到一种暂时有序的线程调度,来保证数据的安全
还是用一段简单的代码案例来做个说明
Java中对象锁可以用于实现线程同步。通过synchronized块持有某个对象的锁。
如之前的秒杀活动,在这里提供超超超超简化用以理解
public class Buyer implements Runnable{ public static void main(String [] args){ Object lock = new Object(); new Thread(new Buyer("buyer-1",lock)).start(); new Thread(new Buyer("buyer-2",lock)).start(); new Thread(new Buyer("buyer-3",lock)).start(); new Thread(new Buyer("buyer-4",lock)).start(); new Thread(new Buyer("buyer-5",lock)).start(); new Thread(new Buyer("buyer-6",lock)).start(); new Thread(new Buyer("buyer-7",lock)).start(); new Thread(new Buyer("buyer-8",lock)).start(); } private String name; private static Integer number = 100; private Object lock; public Buyer(String name,Object lock) { this.name = name; this.lock = lock; } @Override public void run() { synchronized (lock) { number--; System.out.println(name + ":[ now number become " + number + "]"); } }}
所有抢购线程在执行number–操作时都将持有lock对象的锁,直到运行完synchronized块中的代码,然后,其他的线程才会继续竞争cpu(lock的对象锁),如此往复。
从结果看,无论线程的调度顺序如何,都无法影响结果的准确。
buyer-1:[ now number become 99]buyer-4:[ now number become 98]buyer-5:[ now number become 97]buyer-3:[ now number become 96]buyer-2:[ now number become 95]buyer-7:[ now number become 94]buyer-6:[ now number become 93]buyer-8:[ now number become 92]
buyer-1:[ now number become 99]buyer-4:[ now number become 98]buyer-5:[ now number become 97]buyer-3:[ now number become 96]buyer-2:[ now number become 95]buyer-8:[ now number become 94]buyer-7:[ now number become 93]buyer-6:[ now number become 92]
就先写到这里,再总结一段时间,然后会将线程的同步问题掰开揉碎好好总结一下。
- java多线程的理解
- java多线程编程理解
- java 多线程理解
- 轻松理解Java 多线程
- java 多线程理解
- java多线程的理解
- java多线程基础理解
- java 多线程学习理解
- java多线程深入理解
- Java多线程的理解
- Java多线程理解
- Java 多线程 理解
- Java多线程理解
- java多线程理解
- java多线程理解
- java多线程深入理解
- Java多线程理解
- java多线程详细理解!
- C++中的istringstream 的用法
- 级数求和
- 【bzoj4061: [Cerc2012]Farm and factory】
- 行内onclick使用遇坑--------作用域与传入字符串
- Python-count函数
- Java多线程理解
- tomcat报错Exception in thread "http-bio-8080-exec-42"内存溢出...
- 漫道金服荣获2017年度最佳金融创新平台
- 淘淘商城项目:Day1+Day2
- 自定义View实现搜索添加到历史纪录
- Linux下常用软件
- JavaScript 的时间消耗
- ruby的database.yml配置
- 四种常见的 POST 提交数据方式