本篇文章给大家带来的内容是关于java线程同步的实现方法详解(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
为什么线程同步
当我们有多个线程要对同一个资源进行操作的时候,比如说文件,这时候就不能让多个线程同时操作这个文件了。因为当文件共享的时候,多个操作就会产生冲突。相信使用过git进行团队开发的人就会有比价深刻的体会。
这时候就需要引入线程的同步机制。
所谓同步,是指一个一个执行,也就是排队,几个线程排队执行,让线程之间有一个先来后到的关系。这样,就不会产生争抢的现象,也就不会出现冲突。
问题描述
一个有两个线程的程序,第一个线程计算2~1000之间的偶数及个数,第二个线程计算1000~2000之间的偶数及个数。
初步实现
首先,我们根据题目来设计一下实现方式。
1.定义两个线程。这里要定义自己的线程类,然后去设置计算偶数的开始和结束
2.实现计算所给范围内的偶数和偶数个数
3.执行线程
可以看到实现方式很简单。初步实现如下:
1.定义自己的线程类:
public class MyTread extends Thread { private int begin; // 范围开始 private int end; // 范围结束 public MyTread(int begin, int end) { this.begin = begin; this.end = end; } }
2.实现计算偶数以及偶数个数
@Override public void run() { this.getEven(begin, end); } // 获取偶数以及个数 private void getEven(int begin, int end) { int count = 0; System.out.println(begin + "~" + end + "之间的偶数为:"); if (begin % 2 != 0) { begin += 1; } for (; begin <= end; begin += 2) { System.out.print(begin + " "); count++; } System.out.println(); System.out.println("偶数个数为:" + count); }
3.初始化线程,运行
public static void main(String[] args) { MyTread tread1 = new MyTread(2, 500); MyTread tread2 = new MyTread(500, 1000); tread1.start(); tread2.start(); }
注:这里为了展示后面的效果,所以将数字范围减小。
看一下结果:
好像并不是我们想要的效果。我们想要这样的效果:
我们想要每一部分的偶数和偶数个数都在一起,但是我们实现后的效果确实两部分混乱出现的。
程序完善
要解决上面出现的问题,就要用到我们最开始说的线程同步
了。
根据我们开始的介绍,发现实现同步的一个条件就是有一个共享的资源
。那么我们的代码里什么是这个共享的资源
呢?貌似没有。所以先创建一个。
1.建立共享资源
我们这里的共享资源完全就可以是同一个对象
,所以我们就另外建立一个类,用来示例共享资源。
public class Even {}
2.然后在共享类中建立计算偶数的方法:
public class Even { /** * 获取某个范围内偶数以及个数 * @param begin 统计开始 * @param end 统计结束 */ public synchronized void getEven(int begin, int end) { int count = 0; System.out.println(begin + "~" + end + "之间的偶数为:"); if (begin % 2 != 0) { begin += 1; } for (; begin <= end; begin += 2) { System.out.print(begin + " "); count++; } System.out.println(); System.out.println("偶数个数为:" + count); } }
细心的人会发现,这个方法跟我们最开始写的方法有点不同,它多了一个关键字:synchronized
。通过这个关键字,我们就能在执行方法的时候,实现线程同步了。
3.最后在线程中调用共享方法
public class MyTread extends Thread { Even even; @Override public void run() { even.getEven(begin, end); } }
这时候,我们再来执行一下:
实现了我们想要的效果。
最后,附上完整代码:
/** * 偶数类 */ public class Even { /** * 获取某个范围内偶数以及个数 * @param begin 统计开始 * @param end 统计结束 */ public synchronized void getEven(int begin, int end) { int count = 0; System.out.println(begin + "~" + end + "之间的偶数为:"); if (begin % 2 != 0) { begin += 1; } for (; begin <= end; begin += 2) { System.out.print(begin + " "); count++; } System.out.println(); System.out.println("偶数个数为:" + count); } } public class MyTread extends Thread { Even even; private int begin; // 范围开始 private int end; // 范围结束 public MyTread(Even even, int begin, int end) { this.even = even; this.begin = begin; this.end = end; } @Override public void run() { even.getEven(begin, end); } public static void main(String[] args) { Even even = new Even(); MyTread tread1 = new MyTread(even, 2, 500); MyTread tread2 = new MyTread(even, 500, 1000); tread1.start(); tread2.start(); } }
以上是java线程同步的实现方法详解(附代码)的详细内容。更多信息请关注PHP中文网其他相关文章!