`
yuping322
  • 浏览: 93333 次
  • 来自: ...
社区版块
存档分类
最新评论

Java线程学习和总结

阅读更多

线程是Java的一大特色,从语言上直接支持线程,线程对于进程来讲的优势在于创建的代价很小,上下文切换迅速,当然其他的优势还有很多,缺点也是有的,比如说对于开发人员来讲要求比较高,不容易操作,但是Java的线程的操作已经简化了很多,是一个比较成熟的模型。很多时候,我们都用不到线程,但是当我们有一天不走运(或者走运)的时候,我们必须要面对这个问题的时候,应该怎么办呢?本文是我的学习笔记和一些总结,试图解决这个问题,引领还没有接触过Java 线程的开发人员进入一个Java线程的世界,其实很多东西在网路上已经有朋友总结过了,不过我感觉没有比较循序渐进,要么太基础,要么太高深,所以这边我由浅到深的总结一下。但是很显然,我的资历尚浅,能力也很有限,如果有什么错误还望不吝赐教!麻烦发送mail到:yaogao@gmail.com 而且,这些大部份的都有源码,如果需要也可以发mail到这个邮箱,真的非常希望有人能指正我的错误!

(一) 基本的API介绍<o:p></o:p>

1.   如何创建一个可以执行的线程类<o:p></o:p>

       创建一个线程有两个办法:继承Thread类或者实现Runnable接口。

       首先:继承Thread

       这里一般只需要我们来重写run这个方法。下面是代码:

public class SimpleThread extends Thread {<o:p></o:p>

       public SimpleThread() {<o:p></o:p>

              start();<o:p></o:p>

       }<o:p></o:p>

       @Override<o:p></o:p>

    public void run() {<o:p></o:p>

              while (true) {<o:p></o:p>

                     System.out.println(this);<o:p></o:p>

                     // Imply other thread can run now, but we cannot assume that it will<o:p></o:p>

                     // work well every time, actually , most of time we can get the same<o:p></o:p>

                     // result, but not to a certainty.<o:p></o:p>

                     // yield();<o:p></o:p>

                     try {<o:p></o:p>

                            sleep(100);<o:p></o:p>

                     } catch (InterruptedException e) {<o:p></o:p>

                            e.printStackTrace();<o:p></o:p>

                     }<o:p></o:p>

              }<o:p></o:p>

       }<o:p></o:p>

}<o:p></o:p>

其次:实现Runnable接口,代码如下:

       Public class Inner implements Runnable {<o:p></o:p>

              private Thread thread;<o:p></o:p>

              public Inner(String name) {<o:p></o:p>

                     thread = new Thread(this, name);<o:p></o:p>

                     thread.start();<o:p></o:p>

              }<o:p></o:p>

              public void run() {<o:p></o:p>

                     while (true) {<o:p></o:p>

                     try {<o:p></o:p>

                                   Thread.sleep(10);<o:p></o:p>

                            } catch (InterruptedException e) {<o:p></o:p>

                                   throw new RuntimeException(e);<o:p></o:p>

                            }<o:p></o:p>

                     }<o:p></o:p>

              }<o:p></o:p>

2.   几个常用的API<o:p></o:p>

这边介绍几个常见而且重要的的线程API,这边JDK文档有更加详细的说明,其实JDK的文档就是个很好的学习资料,常备很重要哦!

方法

说明

start

使线程开始执行,实际上这个方法会调用下面的run这个方法,如果这个线程已经开始执行,则会扔出IllegalThreadStateException

sleep

是当前已经运行的线程休眠一段时间。如果当前线程已经被别的线程中断的话,将会扔出InterruptedException,而且interrupted标志也会被清空。这个方法有两个版本,具体参看JDK文档。

run

线程执行的业务逻辑应该在这里实现。

join

等待另外一个线程死亡。如果当前线程已经被别的线程中断的话,将会扔出InterruptedException,而且interrupted标志也会被清空。

yield

使当前线程临时的中断执行,来允许其他线程可以执行,因为Java的线程模型实际上映射到操作系统的线程模型,所以对于不同的操作系统,这个方法的就有不同的意义。对于非抢占式Operating System,这个方法使得其他线程得到运行的机会,但是对于抢占式的OS,这个方法没有太多的意义。关于这个方法,后边还有更多的介绍。

wait

Wait方法和后边的两个方法都来自Object。看过Java源码的可以知道,这三个方法都是Native方法,使比较直接的和操作系统打交道的方法。

这个方法的作用是让当前线程等待,直到被唤醒或者等待的时间结束。当前线程进入等待队列的时候,会放弃当前所有的资源,所以当前线程必须获得这些对象的Monitor,否则会扔出IllegalMonitorStateException 关于wait方法的更多,后边会有介绍到。

notify

通知其他线程可以使用资源了。这个方法的使用要求很多,总之需要当前线程获得被调用的notify方法的对象的monitor。比如:

                                                 synchronized (person) {<o:p></o:p>

                                                        person.notify();<o:p></o:p>

                                                 }<o:p></o:p>

其实,获得monitor的方法还有别的,这里简单介绍一下:

1.         执行这个对象的一个同步的方法

2.         执行这个对象的同步块

3.         执行一个同步的静态方法

notifyAll

除了通知所有的线程可以准备执行之外,跟上面的方法要求一样。但是只有一个线程会被选择然后执行,这个就跟优先级和其他状态有关系了。

interrupt

中断线程。

这边只是介绍了几个常用的API,但是非常重要,其他的API可以查看JDK的相关文档。但是在操作系统的概念中,很显然,对于一个线程应该还有别的状态,对,确实还有,但是Java在实现的映射的时候,也实现了这些方法,只是不赞成使用,下面的主题将讨论这些方法以及这些方法的替代方法。

3.   已经不赞成使用的方法<o:p></o:p>

对于一些不应该再使用的东西,有时候被称为反模式antipattern。这些都是概念上的东西,对于我们开发人员来讲,需要做的就是写出好的代码。<o:p></o:p>

方法

说明

stop

强制使当前的线程停止执行。实际上,作为开发人员我们会意识到,线程的复杂程度是没有边际的,而这个方法这样武断的停止一个线程,必然导致问题产生。也就是说,这个方法天生就有问题。比如说一个线程掌握了很多对象,并且改变了其中一些的状态,如果突然当前对象突然被停止,将会释放这些对象的monitor,这个时候被改变状态的对象就是被损坏的对象,其他线程再来操作的时候问题就出来了。

替代的办法就是让当前线程正常结束,不使用这个方法。就是我们设置一些标志,如果这些标志满足的时候,我们结束线程。下面用JDK的例子:

    private Thread blinker;<o:p></o:p>

    public void start() {<o:p></o:p>

        blinker = new Thread(this);<o:p></o:p>

        blinker.start();<o:p></o:p>

    }<o:p></o:p>

    public void stop() {<o:p></o:p>

        blinker.stop();  // UNSAFE!<o:p></o:p>

    }<o:p></o:p>

    public void run() {<o:p></o:p>

        Thread thisThread = Thread.currentThread();<o:p></o:p>

        while (true) {<o:p></o:p>

            try {<o:p></o:p>

                thisThread.sleep(interval);<o:p></o:p>

            } catch (InterruptedException e){<o:p></o:p>

            }<o:p></o:p>

            //do something<o:p></o:p>

        }<o:p></o:p>

}<o:p></o:p>

修改后:<o:p></o:p>

    private volatile Thread blinker;<o:p></o:p>
    public void stop() {<o:p></o:p>
        blinker = null;<o:p></o:p>
    }<o:p></o:p>
    public void run() {<o:p></o:p>
        Thread thisThread = Thread.currentThread();<o:p></o:p>
        //Check the flag<o:p></o:p>
        while (blinker == thisThread) {<o:p></o:p>
            try {<o:p></o:p>
                thisThread.sleep(interval);<o:p></o:p>
            } catch (InterruptedException e){<o:p></o:p>
            }<o:p></o:p>
            //do something<o:p></o:p>
        }<o:p></o:p>

}<o:p></o:p>

当然如果这个方法中间有wait方法的调用的话,而且正在等待,我们可以使用这个办法来结束:<o:p></o:p>

Thread.currentThread().interrupt();

分享到:
评论

相关推荐

    java多线程编程总结

    Java线程的状态包括新建 (`NEW`)、就绪 (`RUNNABLE`)、阻塞 (`BLOCKED`)、等待 (`WAITING`)、超时等待 (`TIMED_WAITING`) 和终止 (`TERMINATED`)。 #### 五、Java线程:线程的同步与锁 - **线程同步** 线程同步...

    Java线程 学习

    ### Java线程学习知识点 #### 一、Java线程概览 - **定义与作用**:线程是在程序中独立且并发执行的路径。在Java中,线程被设计为语言的一部分,而不是作为操作系统的底层工具。每个Java程序至少包含一个主线程,在...

    Java中的多线程学习总结

    ### Java中的多线程学习总结 #### 一、线程与进程的概念 在计算机科学中,**进程**和**线程**是两个重要的概念。早期的Windows 3.x系统中,进程是最小的运行单位。到了Windows 95/NT等操作系统中,除了进程外还...

    Java 多线程学习详细总结

    【Java 多线程学习详细总结】 在Java编程中,多线程是处理并发执行任务的关键技术。本文将深入探讨Java中的多线程概念、实现方式、线程状态转换、线程调度、线程同步以及数据传递等相关知识。 1. **扩展`java.lang...

    Java 多线程学习总结6

    在“Java多线程学习总结6”这个主题中,我们可以深入探讨Java多线程的实现、管理及优化。下面将详细阐述相关知识点。 1. **线程的创建方式** - **继承Thread类**:自定义类继承Thread类,并重写run()方法,创建...

    Java多线程的总结

    Java多线程是Java编程中的一个核心概念,它在现代软件开发中扮演着至关重要的角色。...通过深入学习和实践上述Java多线程的知识点,开发者能够构建出高效、稳定、可控的多线程程序,满足各种复杂的并发需求。

    Java 多线程学习总结归纳(附代码)

    下面是对Java多线程学习的详细解析。 1. **多线程概述**: 多线程是指一个程序内可以同时执行多个独立的执行流,每个执行流被称为一个线程。Java通过Thread类来代表线程,每个线程都有自己的生命周期,包括新建、...

    java线程 线程学习资料 java线程教程

    ### Java线程教程知识点梳理 #### 一、教程概述 - **目标读者**: 本教程主要面向具备丰富Java基础知识但缺乏多线程编程经验的学习者。 - **学习成果**: 学习者能够掌握编写简单的多线程程序的能力,并能够理解和...

    Java多线程学习总结

    本文将深入探讨Java中的线程和进程,以及如何在Java中实现多线程。 首先,理解线程和进程的概念至关重要。线程是操作系统分配CPU时间片的基本单位,它在同一个进程内共享资源,如内存空间。相比进程,线程具有更高...

    java多线程学习资料

    ### Java多线程学习资料知识点解析 #### 一、引言 Java作为一种广泛使用的编程语言,在并发编程领域具有独特的优势。多线程是Java中实现并发处理的核心技术之一,能够显著提升程序的性能和响应性。本文将深入探讨...

    java多线程学习-ftp上传

    总结来说,Java多线程学习和FTP上传结合,可以帮助我们构建高效、可控的文件上传服务。通过线程池,我们可以更好地管理并发任务,优化资源使用,提高FTP上传的性能。学习这些内容对于Java开发者尤其重要,尤其是在...

    Java多线程学习总结.pdf

    Java多线程学习总结.pdf

    java线程学习教程

    ### Java线程学习教程知识点详解 #### 一、教程概览 - **适用人群**: 本教程主要面向那些已经熟练掌握了Java语言基本语法和应用,但对于多线程和并发编程经验较少的Java开发者。 - **目标**: 学习者通过本教程的...

Global site tag (gtag.js) - Google Analytics