一、什么是多线程?

很显然,一随便编敲一段简单的小代码,从main方法开始运行,计算机是一条一条地从上而下的串行执行程序。那如果我们要同时执行两个任务呢?就比如你用浏览器上网看网页的时候,你还能同时登QQ,还能同时下载电影……这些任务都是并行执行的。在计算机的任务管理器里可以看到一个一个的正在运行的程序任务,这些程序就是一个个一个的进程,而大多数进程下面都已多条线程同时执行,所以,多线程其实就是多个任务在同时执行。

虽然是多线程,但是CPU执行命令仍然是一条一条执行的。然而计算机CPU只有一个,虽然多核计算机能够有虚拟多CPU的技术(这是我自己对多核CPU的理解,不够准确请见谅),但是相对于计算机要实现的线程数量,简直少的可怜。所以,当多线程在硬件实现的时候,CPU的处理方式是进行分时处理(TDMA时分多址有没有!!?)。什么意思呢,就是在一段时间执行这一条线程,一段时间执行另外一条线程,所有的具有执行资格的线程进行随机的获得CPU的执行权。CPU的运算速度快的惊人,因此我们感觉上其实就是多线程在并发执行了。

二、JAVA中多线程的使用,Thread类

“一切皆对象”在JAVA语言中是一个永恒不变的定理,自然线程这玩意同样有个对象进行包装。那就是Thread类。这个对象实现了一个Runnable接口,这个接口很简单,就一个run方法。

对于要多线程执行任务,可以通过如下两种方法来实现多线程:

1、继承Thread类

通过将要实现的任务封装成方法,再封装成对象,然后继承Thread类,将任务方法写进run方法之中,在再父线程中用start方法启动就可以了。比如如下开启一个线程的代码

package com.qyz.thread;public class ThreadDemo1 {public static void main(String[] args) {Thread t1 = new Demo("第一个线程");//start()开启线程
        t1.start();//输出:第一个线程:被打开了
    }
}
//继承了Thread的对象
class Demo extends Thread{public Demo(String name){//父类构造方法中可以给线程命名super(name);}//重写run方法
    @Overridepublic void run(){//打印线程名称System.out.println(Thread.currentThread().getName() + ":被打开了");}
}

2、通过实现Runnable接口

方法一的线程开启方法有一个问题,就是当一个类的的继承体系结构之中,只有部分子类需要开启新的线程执行任务,但由于是单继承的,继承了某个父类的子类不可能再继承Thread方法,因此只有通过实现

Runnable方法来开启线程。

1、某个类实现Runnable,并重写run方法,封装需要新开启线程实现的任务。2、新建Thread(Runnable target,name)对象。将Runnable对象封装进线程对象中。3、开启线程start()

 1 package com.qyz.thread;
 2
 3 public class ThreadDemo2 {
 4
 5     public static void main(String[] args) {
 6         Thread t1 = new Thread(new Demo2(),"第二个线程");
 7         //start()开启线程
 8         t1.start();
 9         //输出:第二个线程:被打开了
10     }
11 }
12 //实现了Runnable接口的对象
13 class Demo2 implements Runnable{
14     //重写run方法
15     @Override
16     public void run(){
17         //打印线程名称
18         System.out.println(Thread.currentThread().getName() + ":被打开了");
19     }
20 }

三、多线程之间的同步问题

多线程好吗?当然好,但是会有一个问题需要注意!那就是同步问题。在多个线程访问同一对象数据时?有多条操作命令,本来想的是等一个线程操作完该对象后,另外一个线程再操作,但是由于CPU是随机分时执行线程,因此有可能当一个线程对共享对象操作到一半时,CPU就切向另外一个线程,导致出现意外的输出结果。这样的问题一半很难排查,因此需要在编写代码的时候多加注意!

没有同步的买卖票事例

 1 package com.qyz.thread;
 2
 3 public class TickerDemo1 {
 4     public static void main(String[] args) {
 5         SaleTicket st = new SaleTicket();
 6         //实现3个线程
 7         Thread t1 = new Thread(st, "1号卖票员");
 8         Thread t2 = new Thread(st, "2号卖票员");
 9         Thread t3 = new Thread(st, "3号卖票员");
10         //开启线程
11         t1.start();
12         t2.start();
13         t3.start();
14     }
15 }
16 class SaleTicket implements Runnable{
17     //总共100张票
18     private int num = 100;
19     @Override
20     public void run() {
21         while(this.num > 0){
22             //这个代码太简单,所以让线程睡一会,突出同步问题
23             try {Thread.sleep(10);} catch (Exception e) {}
24             System.out.println(Thread.currentThread().getName() + "******" + num--);
25         }
26     }
27 }

本来不该出现的0号票出现了,意外情况

解决方法:加锁

多线程中的锁其实就像一扇门,一个线程进去之后,把门锁上,另外一个线程就不能进来,直到门里面的线程执行完毕出来。

JAVA中实现同步锁通过关键字synchronized,有以下方法

1、同步代码块,需要同步的命令封装进一个代码块中,加上一个对象做锁即可

 1 class SaleTicket implements Runnable{
 2     //总共100张票
 3     private int num = 100;
 4     //一个object对象充当锁
 5     private Object lock = new Object();
 6     @Override
 7     public void run() {
 8         while(true){
 9             //同步代码块封装
10             synchronized (lock) {
11                 if(this.num > 0){
12                     //这个代码太简单,所以让线程睡一会,突出同步问题
13                     try {Thread.sleep(10);} catch (Exception e) {}
14                     System.out.println(Thread.currentThread().getName() + "******" + num--);
15                 }else
16                     break;
17             }
18         }
19     }
20 }

输出如下

问题解决!

2、同步函数

函数是一种封装,代码块也是一种封装,那能不能结合在一起呢?sure!那就是通过关键字将将方法变成同步函数。

 1 class SaleTicket implements Runnable{
 2     //总共100张票
 3     private int num = 100;
 4     @Override
 5     public void run() {
 6         while(true){
 7             this.sale();
 8         }
 9     }
10     //通过封装成同步函数来实现
11     private synchronized void sale(){
12         if(this.num > 0){
13             //这个代码太简单,所以让线程睡一会,突出同步问题
14             try {Thread.sleep(10);} catch (Exception e) {}
15             System.out.println(Thread.currentThread().getName() + "******" + num--);
16         }
17     }
18 }

成功解决!

转载于:https://www.cnblogs.com/njupt-Qsimple/p/5618491.html

JAVA多线程学习(一)相关推荐

  1. Java多线程学习处理高并发问题

    在程序的应用程序中,用户或请求的数量达到一定数量,并且无法避免并发请求.由于对接口的每次调用都必须在返回时终止,因此,如果接口的业务相对复杂,则可能会有多个用户.调用接口时,该用户将冻结. 以下内容将 ...

  2. java多线程学习-java.util.concurrent详解

    http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...

  3. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  4. java多线程学习笔记。

    java多线程学习笔记 线程的优缺点: 多线程的好处: 充分利用多处理核心,提高资源的利用率和吞吐量. 提高接口的响应效率,异步系统工作. 线程的风险: 安全危险(竞争条件):什么坏事都没有发生.在没 ...

  5. 【转】Java 多线程学习

    原网址:https://www.cnblogs.com/yjd_hycf_space/p/7526608.html Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实J ...

  6. 转:Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  7. Java多线程学习——01

    Java多线程学习--01 1.核心概念 程序:是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念 进程Process:是执行程序的一次执行过程,它是一个动态的概念,是系统资源分配的单 ...

  8. java线程学习,GitHub - zksir/thread: Java多线程学习

    Java多线程学习 threadcoreknowledge包----线程核心知识基础 createthreads包 创建线程 1.实现多线程的方法是1种还是2种还是4种? Oracle官方:2种,一种 ...

  9. Java多线程学习之路(四)---死锁(DeadLock)

    Java多线程学习之路(四)-死锁(DeadLock) 1.定义 死锁就是多个线程在竞争共享资源的时候,相互阻塞,不能脱身的状态(个人理解).其实死锁一定程度上可以看成一个死循环. 举个现实生活中的例 ...

  10. Java多线程学习 (超详细总结)

    Java多线程学习 一.概要 二. JAVA 线程实现/创建方式 2.1 继承Thread 类 2.2 实现 Runnable 接口 2.3 Thread和Runnable的区别 2.4 总结 三.线 ...

最新文章

  1. docker-2-简单使用docker-ce
  2. Android layout布局属性、标签属性总结大全
  3. C#操作SQL Server通用类
  4. AngularJs学习笔记--unit-testing
  5. 如何用C#和ADO.NET建立一个数据绑定网格(转载)
  6. oracle索引总结
  7. Extended Euclidean algorithm(扩展欧几里得算法Matlab实现)
  8. sap gateway data provider - /IWFND/IF_MGW_CORE_RUNTIME
  9. [链表] --- 反转链表(leetcode 206)
  10. Linux 用户 和 用户组 管理 (添加、删除、修改)及说明
  11. dataset中的数据批量导入oracle数据库,C#如何把某个文件夹下的所有Excel文件导入Oracle数据库。详细点!...
  12. Mysql常用的几种join连接方式
  13. 蓝桥杯2017年第八届C/C++省赛B组第一题-购物单
  14. tcp连接python_python网络编程--TCP连接的三次握手(三报文握手)与四次挥手
  15. chrome插件离线安装包(.crx)下载
  16. 如何建立自己的博客网站
  17. 新仙女木事件和农耕文明_后农业文明的排列
  18. 基于select2的二级联动
  19. R语言绘图—快速绘制Lollipop图
  20. 【HZHE004】黄子涵学习Echarts

热门文章

  1. Android开发工具之Android Studio---版本控制SVN使用(二)
  2. NOIP2018比赛总结
  3. JZOJ 5183. 【NOIP2017提高组模拟6.29】小T的钢琴
  4. 编译原理lr(0)c语言,关于编译原理:LR(1)LR(0)文法判断?
  5. python redis模块_python redis 模块 官方文档(中)
  6. 打印机支持打印html页面吗,vue下调用打印功能,打印html页面
  7. 文本分类入门(十一)特征选择方法之信息增益
  8. 天天向上续python3.3_python3的一些实例(3.1-3.8)
  9. 一般将来时语法课教案_【语法视频课】第43~45节(虚拟语气)
  10. ajax id sort,ajax返回的json内容进行排序使用sort()方法实现