0

0

Java多线程基本使用

高洛峰

高洛峰

发布时间:2016-11-14 09:32:47

|

1920人浏览过

|

来源于php中文网

原创

一、概念

1.进程

1.1进程:是一个正在进行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。

1.2线程:就是进程中一个独立的控制单元,线程在控制着进程的执行,一个进程中至少有一个线程。

1.3举例java VM:

立即学习Java免费学习笔记(深入)”;

Java VM启动的时候会有一个进程java.exe,该进程中至少有一个线程在负责java程序的运行,而且这个线程运行的代码存在于main方法中,该线程称之为主线程。扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程

2.多线程存在的意义:提高执行效率

二、多线程的创建

1.多线程创建的第一种方式,继承Thread类

1.1定义类继承Thread,复写Thread类中的run方法是为了将自定义的代码存储到run方法中,让线程运行

1.2调用线程的start方法,该方法有两个作用:启动线程,调用run方法

1.3多线程运行的时候,运行结果每一次都不同,因为多个线程都获取cpu的执行权,cpu执行到谁,谁就运行,明确一点,在某一个时刻,只能有一个程序在运行。(多核除外),cpu在做着快速的切换,以到达看上去是同时运行的效果。我们可以形象把多线程的运行行为在互抢cpu的执行权。这就是多线程的一个特性,随机性。谁抢到,谁执行,至于执行多久,cpu说了算。

public class Demo extends Thread{ 
    public void run(){ 
        for (int x = 0; x < 60; x++) { 
            System.out.println(this.getName()+"demo run---"+x); 
        } 
    } 
     
    public static void main(String[] args) { 
        Demo d=new Demo();//创建一个线程 
        d.start();//开启线程,并执行该线程的run方法 
        d.run(); //仅仅是对象调用方法,而线程创建了但并没有运行 
        for (int x = 0; x < 60; x++) { 
            System.out.println("Hello World---"+x); 
        } 
    } 
 
}

2 创建多线程的第二种方式,步骤:

2.1定义类实现Runnable接口

2.2覆盖Runnable接口中的run方法:将线程要运行的代码存放到run方法中

2.3.通过Thread类建立线程对象

2.4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数

为什么要将Runnable接口的子类对象传递给Thread的构造函数:因为自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去执行指定对象的run方法,就必须明确该run方法的所属对象

2.5.调用Thread类的start方法开启线程并调用Runnable接口子类的方法

/* 
 * 需求:简易买票程序,多个窗口同时卖票 
 */ 
public class Ticket implements Runnable { 
    private static int tick = 100; 
    Object obj = new Object(); 
    boolean flag=true; 
 
    public void run() { 
        if(flag){ 
            while (true) { 
                synchronized (Ticket.class) { 
                    if (tick > 0) { 
                        System.out.println(Thread.currentThread().getName() 
                                + "code:" + tick--); 
                    } 
                } 
            } 
        }else{ 
            while(true){ 
                show(); 
            } 
        } 
         
    } 
 
    public static synchronized void show() { 
        if (tick > 0) { 
            System.out.println(Thread.currentThread().getName() + "show:" 
                    + tick--); 
        } 
    } 
 
} 
 
class ThisLockDemo { 
    public static void main(String[] args) { 
        Ticket t = new Ticket(); 
 
        Thread t1 = new Thread(t); 
        try { 
            Thread.sleep(10); 
        } catch (Exception e) { 
            // TODO: handle exception 
        } 
        t.flag=false; 
        Thread t2 = new Thread(t); 
        //Thread t3 = new Thread(t); 
        //Thread t4 = new Thread(t); 
 
        t1.start(); 
        t2.start(); 
        //t3.start(); 
        //t4.start(); 
    } 
}

3.实现方式和继承方式有什么区别

3.1.实现方式避免了单继承的局限性,在定义线程时建议使用实现方式

3.2.继承Thread类:线程代码存放在Thread子类run方法中

3.3.实现Runnable:线程代码存放在接口的子类run方法中

4.多线程-run和start的特点

4.1为什么要覆盖run方法呢:

Thread类用于描述线程,该类定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法,也就是说该Thread类中的run方法,用于存储线程要运行的代码

5.多线程运行状态

创建线程-运行---sleep()/wait()--冻结---notify()---唤醒

创建线程-运行---stop()—消亡

华友协同办公自动化OA系统
华友协同办公自动化OA系统

华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、

下载

创建线程-运行---没抢到cpu执行权—临时冻结

6.获取线程对象及其名称

6.1.线程都有自己默认的名称,编号从0开始

6.2.static Thread currentThread():获取当前线程对象

6.3.getName():获取线程名称

6.4.设置线程名称:setName()或者使用构造函数

public class Test extends Thread{ 
     
    Test(String name){ 
        super(name); 
    } 
     
    public void run(){ 
        for (int x = 0; x < 60; x++) { 
            System.out.println((Thread.currentThread()==this)+"..."+this.getName()+" run..."+x); 
        } 
    } 
} 
 
class ThreadTest{ 
    public static void main(String[] args) { 
        Test t1=new Test("one---"); 
        Test t2=new Test("two+++"); 
        t1.start(); 
        t2.start(); 
        t1.run(); 
        t2.run(); 
        for (int x = 0; x < 60; x++) { 
            System.out.println("main----"+x); 
        } 
    } 
}

三、多线程的安全问题

1.多线程出现安全问题的原因:

1.1.当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误

1.2.解决办法:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行

1.3.java对于多线程的安全问题提供了专业的解决方式,就是同步代码块:

Synchronized(对象){需要被同步的代码},对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取cpu执行权,也进不去,因为没有获取锁

2.同步的前提:

2.1.必须要有2个或者2个以上线程

2.2.必须是多个线程使用同一个锁

2.3.好处是解决了多线程的安全问题

2.4.弊端是多个线程需要判断锁,较消耗资源

2.5.同步函数

定义同步函数,在方法钱用synchronized修饰即可

/* 
 * 需求: 
 * 银行有一个金库,有两个储户分别存300元,每次存100元,存3次 
 * 目的:该程序是否有安全问题,如果有,如何解决 
 * 如何找问题: 
 * 1.明确哪些代码是多线程代码 
 * 2.明确共享数据 
 * 3.明确多线程代码中哪些语句是操作共享数据的 
 */ 
 
public class Bank { 
 
    private int sum; 
 
    Object obj = new Object(); 
 
    //定义同步函数,在方法钱用synchronized修饰即可 
    public synchronized void add(int n) { 
        //synchronized (obj) { 
            sumsum = sum + n; 
            try { 
                Thread.sleep(10); 
            } catch (InterruptedException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
            System.out.println("sum=" + sum); 
        //} 
 
    } 
 
} 
 
class Cus implements Runnable { 
    private Bank b = new Bank(); 
 
    public void run() { 
        for (int x = 0; x < 3; x++) { 
            b.add(100); 
        } 
    } 
} 
 
class BankDemo { 
    public static void main(String[] args) { 
        Cus c = new Cus(); 
        Thread t1 = new Thread(c); 
        Thread t2 = new Thread(c); 
 
        t1.start(); 
        t2.start(); 
    } 
}

6.同步的锁

6.1函数需要被对象调用,那么函数都有一个所属对象引用,就是this.,所以同步函数使用的锁是this

6.2.静态函数的锁是class对象

静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,类名.class,该对象的类型是Class

6.3.静态的同步方法,使用的锁是该方法所在类的字节码文件对象,类名.class

/* 
 * 需求:简��买票程序,多个窗口同时卖票 
 */ 
public class Ticket implements Runnable { 
    private static int tick = 100; 
    Object obj = new Object(); 
    boolean flag=true; 
 
    public void run() { 
        if(flag){ 
            while (true) { 
                synchronized (Ticket.class) { 
                    if (tick > 0) { 
                        System.out.println(Thread.currentThread().getName() 
                                + "code:" + tick--); 
                    } 
                } 
            } 
        }else{ 
            while(true){ 
                show(); 
            } 
        } 
         
    } 
 
    public static synchronized void show() { 
        if (tick > 0) { 
            System.out.println(Thread.currentThread().getName() + "show:" 
                    + tick--); 
        } 
    } 
 
} 
 
class ThisLockDemo { 
    public static void main(String[] args) { 
        Ticket t = new Ticket(); 
 
        Thread t1 = new Thread(t); 
        try { 
            Thread.sleep(10); 
        } catch (Exception e) { 
            // TODO: handle exception 
        } 
        t.flag=false; 
        Thread t2 = new Thread(t); 
        //Thread t3 = new Thread(t); 
        //Thread t4 = new Thread(t); 
 
        t1.start(); 
        t2.start(); 
        //t3.start(); 
        //t4.start(); 
    } 
}

7.多线程,单例模式-懒汉式

懒汉式与饿汉式的区别:懒汉式能延迟实例的加载,如果多线程访问时,懒汉式会出现安全问题,可以使用同步来解决,用同步函数和同步代码都可以,但是比较低效,用双重判断的形式能解决低效的问题,加同步的时候使用的锁是该类锁属的字节码文件对象

/* 
 * 单例模式 
 */ 
//饿汉式 
public class Single { 
    private static final Single s=new Single(); 
    private Single(){} 
    public static Single getInstance(){ 
        return s; 
    } 
 
} 
 
//懒汉式 
class Single2{ 
    private static Single2 s2=null; 
    private Single2(){} 
    public static Single2 getInstance(){ 
        if(s2==null){ 
            synchronized(Single2.class){ 
                if(s2==null){ 
                    s2=new Single2();     
                } 
            } 
        } 
        return s2; 
    } 
} 
 
class SingleDemo{ 
    public static void main(String[] args) { 
        System.out.println("Hello World"); 
    } 
}

8.多线程-死锁

同步中嵌套同步会出现死锁

/* 
 * 需求:简易买票程序,多个窗口同时卖票 
 */ 
public class DeadTest implements Runnable { 
    private boolean flag; 
 
    DeadTest(boolean flag) { 
        this.flag = flag; 
    } 
 
    public void run() { 
        if (flag) { 
            synchronized(MyLock.locka){ 
                System.out.println("if locka"); 
                synchronized(MyLock.lockb){ 
                    System.out.println("if lockb"); 
                } 
            } 
        } else { 
            synchronized(MyLock.lockb){ 
                System.out.println("else lockb"); 
                synchronized(MyLock.locka){ 
                    System.out.println("else locka"); 
                } 
            } 
        } 
    } 
} 
 
class MyLock{ 
    static Object locka=new Object(); 
    static Object lockb=new Object(); 
} 
 
class DeadLockDemo { 
    public static void main(String[] args) { 
        Thread t1 = new Thread(new DeadTest(true)); 
        Thread t2 = new Thread(new DeadTest(false)); 
 
        t1.start(); 
        t2.start(); 
    } 
}
java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 10.2万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.1万人学习

C# 教程
C# 教程

共94课时 | 5.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号