多线程初识

多线程对于有一定开发经验的程序员来说肯定不会陌生,不过相信很多人跟我一样,平时其实没有那么多的多线程实例去做,即使有可以直接使用spring来实现简单的使用,更多的是在面试中,一般都会涉及,特别是大公司的面试。

在阿里的初面中,我就被刷下来,失落感是显而易见的,虽然面试官也坦诚,如果我去了阿里也是做应用,面试问的这些东西也不会有太多涉及,面试门槛高,所以为了去大公司也得耐心的了解。当然面试官也说了,如果你知道这些偏僻的内容,对工作某个点是有用的,我同意这个说法。

所以,对于多线程这部分耐心看下来,对于找工作或者技术提升都是有用的。与君共勉!

文章借鉴于《Java多线程编程实战指南(设计模式篇)》 黄文海/著,以及极客学院多线程视频http://search.jikexueyuan.com/course/?q=%E5%A4%9A%E7%BA%BF%E7%A8%8B。

一,为什么要有多线程?

多线程的前提是各种设备有多个cpu,这样多个cpu能够并行的进行计算。

好处是:

1,吞吐量变大(即能够同时接收多个请求)

2,提高响应性(一个线程比较慢时,其他线程可以继续工作)

3,充分利用cpu资源。可以简单的理解,就是以前一个人做的事情,可以多个人独立分担去做了。

由于是多个线程独立的去做,那么肯定也会产生一些问题。

1,线程安全的问题:多个线程共享数据时,如果没有做相应的措施,那么就会产生数据一致性的问题,如读取脏数据(过期数据),丢失更新(某些线程做的更新被其他线程做的更新覆盖)

2,线程生命特征问题:单线程时一个线程串行执行不会产生问题,但是多个线程就会产生调度的问题,包括死锁,活锁(由于资源有限,调度问题,某个线程一直得不到资源)

3,上下文切换开销:一个线程的状态变更,调度停止线程的执行时,会保存该线程的上下文,即当时的环境状态,当重新执行时,需要恢复当时的环境状态,这个过程会产生开销。

4,可靠性 :线程之间是独立的,一方面一个线程意外终止了不会影响其他线程。另外一方面由于线程共享同一个进程中的资源,如果一个线程内存泄漏导致jvm崩溃停止,那么其他的线程也会停止。

通俗的来说:

有一个土堆要挖土,单线程的情况就是1个挖土机自己慢慢的挖,多线程就是10个挖土机同时来挖,好处就是快,坏处就是10个机器就会有调度的问题,保证不会抢夺资源、摩擦等问题,需要合理的处理调度。

二,线程的状态:

NEW:一个线程刚被创建,还未start(),一个线程只能一次处于此状态。

RUNNABLE:包括READY和RUNNING,线程执行start()之后就是READY状态,此时等待调度系统,被调用中就是RUNNING状态。如果执行yield()方法或者调度系统的原因,RUNNING状态也会变成READY状态,两者是能相互转化的。

BLOCKED:阻塞状态,即线程请求资源被其他线程调用,当其他资源使用完成之后,线程可以变为RUNNABLE状态。

WAITTING:无限制的等待其他线程先执行,才能执行。和BLOCKED的区别在于BLOCKED是线程获得不了资源被动的等待,WAITTING是主动的被调用者等待,相同点是需要等待别人执行完成才能执行。Object.wait() Thread.join() LockSupport.park()执行时会编程WAITTING状态,调用Object.notify() Object.notifyAll() LockSupport.unpark()能够编程RUNNABLE状态。

TIME_WAITTING:有闲时间的等待,比如等待1秒。

TERMINATED:终止状态,正常执行结束,或者跑出异常之后,都会编程这个状态。

总而言之:一个线程一定有一个NEW TERMINATED状态,其他状态可能都会有相互转化。(状态图见附件)

三,线程的实现

我们对线程的操作,基本基于对java.lang.Thread类来操作,Thread也是实现了Runnable接口。

线程实现 ① 实现Runnable接口,实现run方法,Thread类有一个传入Runnable实现的构造器,获得Thread ② 集成Thread类,重写run方法,获得Thread。

com.try2better.threads.test_01_instance;

Instance {

    main(String[] args) {
        Thread t1 = Thread(MyRunnable());
        t1.start();Thread t2 = MyThread();
        t2.start();
    }

    MyRunnable Runnable{
        run() {
            System..println(Thread.().getName());
        }
    }

    MyThread Thread{

        run(){
            System..println(Thread.().getName());
        }
    }
}

四,线程常用方法

1,t.start()启动

2,t.isAlive()启动前是false,启动后是true

3,Thread.currentThread()获得当前线程

4,Thread.sleep(1000)睡眠

5,t.join()强行执行

6,t.yield()礼让

五,线程同步

多个线程占用相同的资源,为了避免脏数据的问题。

com.try2better.threads.test_01_instance;

Synchronization {

    main(String[] args) {
        MyRunable r = MyRunable();
         t1 = (r,);
         t2 = (r,);
         t3 = (r,);

        t1.start();
        t2.start();
        t3.start();
    }

}

MyRunable Runnable{

    Integer = ;

    run() {
        (i = ; i < ; i++) {
            sell();
        }
    }

    sell(){

            (> ){
                {
                    .();
                } (InterruptedException e) {
                    e.printStackTrace();
                }
                System..println(.().getName() + + --);

        }
    }
}

打印结果:

窗口1卖出一张,剩余车票:4

窗口3卖出一张,剩余车票:3

窗口2卖出一张,剩余车票:2

窗口3卖出一张,剩余车票:1

窗口1卖出一张,剩余车票:0

对比没有家synchronized关键字结果:

窗口2卖出一张,剩余车票:4

窗口3卖出一张,剩余车票:3

窗口1卖出一张,剩余车票:2

窗口2卖出一张,剩余车票:1

窗口3卖出一张,剩余车票:0

窗口1卖出一张,剩余车票:-1

窗口2卖出一张,剩余车票:-2

对共享的变量或者方法上加上synchronized,也可以在代码块上加上这个关键字。

六,线程优先级

t1.setPriority(Thread.);t1.setPriority(Thread.);t1.setPriority(Thread.);

目前理解不深,之后补充。

时间: 2024-10-27 06:18:59

多线程初识的相关文章

【小白的java成长系列】——多线程初识(多人买票问题)

本来这节内容是要到后面来说的,因为最近在弄并发的问题,推荐一本书<java并发编程实战>,深入的讲解了多线程问题的.本人最近也刚好在看这本书,还不错的~ 多线程的相关概念,就不用说了的,自己可以去网上查找,有一大堆关于它的讲解~ 先来看看买票的程序: package me.javen.thread.one; public class TicketDemo { public static void main(String[] args) { // 使用Thread类的方式 // TicketTh

spring中controller

提示:原网站已由百度转码,以便在移动设备上查看. 第七城市 (Portal 开发读书笔记)Spring Portlet MVC 测试Controller 2012-04-28 16:32:44 - - 点击数: 175 测试Spring Portlet MVC 中的Controller有两种方法,一种是用mock对象,一种是用TestContext框架 测试1:用mock 对象测试Controller.我们把所有Controller用到或者依赖的对象全部mock掉. public class A

java学习笔记之初识多线程

初识多线程 一.进程的认识: 1.进程的理解: 进程可以理解成正在执行的任务,就是正在运行的程序,进程又分为两种,一种是前台进程,就是我们很直观看见的,另一种是后台进程,就是操作系统启动就有的(系统级的进程),每个进程运行之后都会占用一定的cpu和内存资源: 比如说:我们打开window任务管理器就可以看到有很多的进程,里面有用户开启的,也有操作系统启动的进程 2.进程的调度: 也就是那么多的进程,cpu是怎样运行的呢? 采用时间片轮转法 二.线程认识 1.线程的理解 线程是在进程的内部运行的执

初识多线程

多线程对于有一定开发经验的程序员来说肯定不会陌生,不过相信很多人跟我一样,平时其实没有那么多的多线程实例去做,即使有可以直接使用spring来实现简单的使用,更多的是在面试中,一般都会涉及,特别是大公司的面试. 在阿里的初面中,我就被刷下来,失落感是显而易见的,虽然面试官也坦诚,如果我去了阿里也是做应用,面试问的这些东西也不会有太多涉及,面试门槛高,所以为了去大公司也得耐心的了解.当然面试官也说了,如果你知道这些偏僻的内容,对工作某个点是有用的,我同意这个说法. 所以,对于多线程这部分耐心看下来

从头认识java-17.2 基本的线程机制(1)-初识多线程-2

接着上一个章节,我们这一章节介绍一下多线程的注意点. 线程间执行的顺序和时间是不同的 我们修改一下上一章节的代码: package com.ray.ch17; public class Test { public static void main(String[] args) { for (int i = 5; i < 8; i++) { DoneMission doneMission = new DoneMission(i); Thread thread = new Thread(doneMi

初识多线程之基础知识与常用方法

1.线程与进程的描述: 1.1进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1~n个线程.(进程是资源分配的最小单位) 1.2线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小.(线程是cpu调度的最小单位) 2.实现多线程的常用方式: 继承Thread类    extends Thread 实现Runnable接口  implements Runnable 内部匿名类 Thread t = new Th

Java多线程编程初识

每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务.通常由操作系统负责多个线程的调度和执行. Java对多线程的支持是非常强大的,他屏蔽掉了许多的技术细节,让我们可以轻松的开发多线程的应用程序. Java里面实现多线程,有2个方法: 1.继承 Thread类 public clas

多线程(一)初识多线程

一.环境 idea 二.为什么使用多线程 俗话说:众人拾柴火焰高.为什么不让一个人去拾柴呢!!!当然是团结啦!!但是最总要的是提高效率 所以在程序中也是一样,你可以讲一个线程看做一个人,为了加快程序效率就出现了多线程. 三.什么是线程 面试题:线程和进程的区别是什么 答:线程是程序的一条运行途径,进程是一个线程集合 四.创建线程的方式 多线程执行我们默认忽略极小误差默认是同时执行的,关于谁先执行就看谁能先强到CPU的执行权 4.1实现Thread类 public class ThreadTest

IOS -多线程 - GCD - 初识

1. 什么是GCD a. 全称是Grand Center Dispatch b. 纯C语言,提供了非常多强大的函数 2. GCD的优势 a. GCD是苹果公司为多核的并行运算提出的解决方案 b. GCD会自动利用更多的CPU内核(比如双核.四核) c. GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程) d. 程序员只要告诉GCD想要执行什么任务,不需要编写任何线程管理的代码 3. GCD两个核心概念--任务和队列 任务:要执行的操作(方法) 使用block封装,block 就是一个