美文网首页
Java多线程

Java多线程

作者: 8502b07ac52c | 来源:发表于2017-11-14 16:50 被阅读8次

    一、简介

    在讲线程之前我想谈谈我对线程的理解,在这里我想跟进程区分开来讲。我们的windows系统是可以多个应用同时运行的,我们可以同时进行QQ聊天,网页搜索等等。我们可以认为一个应用就是一个进程。而线程是我们程序的执行路径,我们认为单线程的程序是只有一条执行路径的,根据代码书写,从上往下依次执行。多线程的程序则有多条执行路径,根据cpu分配 的时间片段来执行响应的程序。

    二、java多线程的实现

        在java中主要提供两种方式实现线程,一种是继承java.lang.Thread类另一种则是通过实现java.lang.Runable接口。

    1,继承java.lang.Thread类

    图1

        我们通过继续Thread创建自己的线程对象,在继承Thread对象时一定要重现Thread的run方法;run方法是线程启动后执行的方法,但是启动线程则是通过start方法。

    2,实现java.lang.Runable接口

    图2

    我们通过实现Runnable接口来创建MyRunnable类,在实现Runnable接口时会要求重写run方法。通过Thread的Runnable的构造来创建线程,并启动线程。

    图3

    3,线程同步

    所谓线程同步是在多线程中,为了解决多个线程抢占同一资源所设定的线程锁的机制。我们想象这样的场景,假如你有500元存在某家银行,一天拿着钱去银行ATM取钱,假如你取300,ATM给你300的同时会在你的账户中扣去300,假如以此同时在ATM没来得及扣时,你的老爸也去柜台取300,那么银行会发现你的当时的余额确实还有500,你爸也可以成功地取到300,那么就会造成你账户只要500,但你爸和你总共却能取600。这就是线程不同步造成的。

    接下来我演示一个线程不同步的例子。

    首先我创建一个Operator类,在这个类中有一个tickNum的私有静态变量。我们做一个查询,查询前先tickNum--,然后输出。

    图4

    接下来我们创建两个线程来调用上面的Operator的searchTick()方法,观察输出的结果。

    图5

    会发现查询的结果跟我们的想要的不一样,我们来分析一下。我们先启动的是线程一,线程一开始执行到tickNum--后睡眠了,此时线程二开始执行tickNum--,此时线程二也睡眠了,又跑到了线程一,此时tickNum在线程二操作后已经变成了0,所以上面的打印结果。如何解决这种线程不同步的问题,我们有如下两种方式。

    (1)syschronized代码块

    图6

    我们用synchronized(Object){}包裹起来,这样当前对象(包含变量)就会被锁定,直到执行完{}里面的操作。

    (2)syschronized方法

    图7

    这种方式是将方法直接设置为同步方法,用关键字synchronized修饰方法。这里要主要的是这个synchronized的本质是锁定当前对象(包含变量);

    4,死锁现象

    上面我们使用线程同步的方法来解决多个线程访问同一资源时会出现的问题。但是线程同步同样会带了另一个问题,那就是死锁现象。我们知道线程同步是通过锁来实现的,那么死锁现象是怎么发生的呢?下面我来模拟简单的死锁现象。

    图8

    当我们要完成一个任务必须锁定两个或两个对象以上时就会出现这样的情况,我拿到了一个对象只要再拿到另一个对象就可以完成整个操作,而另一个线程则是先拿到另一个对象,他只要拿到我手中的对象就可以完成操作,但是此时两个线程都锁住了彼此需要的那个对象,导致两个线程都不能完成。但是死锁的现象决解起来比较复杂,目前为止作者也没有深入研究。

    相关文章

      网友评论

          本文标题:Java多线程

          本文链接:https://www.haomeiwen.com/subject/rtgbmxtx.html