Java多线程编程核心技术(一)Java多线程技能(上)

码农登陆

发布时间: 2018-10-11 23:05
关注

前言

文章内容,来自博客园:像风一样。感兴趣的小伙伴可以移步自行关注。本篇文章的下部分,可以在历史文章中观看。

1、进程和线程

一个程序就是一个进程,而一个程序中的多个任务则被称为线程。

进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位。

举个例子:

打开你的计算机上的任务管理器,会显示出当前机器的所有进程,QQ,360等,当QQ运行时,就有很多子任务在同时运行。比如,当你边打字发送表情,边好友视频时这些不同的功能都可以同时运行,其中每一项任务都可以理解成“线程”在工作。

2、使用多线程

在Java的JDK开发包中,已经自带了对多线程技术的支持,可以很方便地进行多线程编程。实现多线程编程的方式有两种,一种是继承 Thread 类,另一种是实现 Runnable 接口。使用继承 Thread 类创建线程,最大的局限就是不能多继承,所以为了支持多继承,完全可以实现 Runnable 接口的方式。需要说明的是,这两种方式在工作时的性质都是一样的,没有本质的区别。如下所示:

2.1、继承 Thread 类

2.2、实现 Runnable 接口

Thread.java 类中的start()方法通知“线程规划器”此线程已经准备就绪,等待调用线程对象的run()方法。这个过程其实就是让系统安排一个时间来调用 Thread 中的 run() 方法,也就是使线程得到运行,多线程是异步的,线程在代码中启动的顺序不是线程被调用的顺序。

3、实例变量与线程安全

自定义线程类中的实例变量针对其他线程可以有共享与不共享之分。当每个线程都有各自的实例变量时,就是变量不共享。共享数据的情况就是多个线程可以访问同一个变量。来看下面的示例:

以上代码定义了一个线程类,实现count变量减一的效果。运行类Runjava代码如下:

打印结果如下:线程C 计算 count = 3线程B 计算 count = 3线程A 计算 count = 2线程D 计算 count = 1线程E 计算 count = 0线程C,B的打印结果都是3,说明C和B同时对count进行了处理,产生了“非线程安全问题”。而我们想要的得到的打印结果却不是重复的,而是依次递减的。

在某些JVM中,i--的操作要分成如下3步:

取得原有变量的值。计算i-1。对i进行赋值。

在这三个步骤中,如果有多个线程同时访问,那么一定会出现非线程安全问题。

解决方法就是使用 synchronized 同步关键字 使各个线程排队执行run()方法。修改后的run()方法:

打印结果:线程B 计算 count = 4线程C 计算 count = 3线程A 计算 count = 2线程E 计算 count = 1线程D 计算 count = 0关于System.out.println()方法先来看System.out.println()方法源码:

虽然println()方法内部使用 synchronized 关键字,但如下所示的代码在执行时还是有可能出现非线程安全问题的。

System.out.println("线程"+Thread.currentThread().getName()+" 计算 count = "+count--);原因在于println()方法内部同步,但 i-- 操作却是在进入 println()之前发生的,所以有发生非线程安全问题的概率。

4、多线程方法

4.1、currentThread()方法

currentThread()方法可返回代码段正在被哪个线程调用的信息。

Thread.currentThread().getName()

4.2、isAlive()方法

方法isAlive()的功能是判断当前的线程是否处于活动状态。

thread.isAlive();

4.3、sleep()方法

方法sleep()的作用是在指定的毫秒数内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是指this.currentThread()返回的线程。

Thread.sleep()

4.4、getId()方法

getId()方法的作用是取得线程的唯一标识。

thread.getId()

尾声

文章内容,来自博客园:像风一样。感兴趣的小伙伴可以移步自行关注。本篇文章的下部分,可以在历史文章中观看。

举报/反馈