Java之多线程同步基础
java学习的道路上呢总有一些麻烦的东西需要花费一些时间去理解,比如个人认为不好搞的多线程.
线程是并列运行的
因为是并列运行,所以有时候会发生资源抢占,从而导致参数变化;
比如酱紫
package seer.线程;
public class SumArray {
private int sum;
//在这个地方sumArry()没有被同步 没有加sync...
public int sumArray(int[] sums) {
sum = ; //重置 初始化sum
for (int i = ; i < sums.length; i++) {
sum += sums[i];
try {
Thread.sleep(); //发生任务切换时,有意允许切换的发生(如果加了synchronized就绝对不可能发生了.)
} catch (InterruptedException e) {
System.out.println("线程中断");
e.printStackTrace();
}
}
return sum;
}
}
//===========================================================================================================
class MyThread implements Runnable {
Thread thrd;
static SumArray sa = new SumArray();
int[] a;
int answer;
//构造一个线程
public MyThread(String name, int[] nums) {
thrd = new Thread(this, name);
a = nums;
}
//创建一个工厂方法用来创建和启动线程
public static MyThread createAndStart(String name, int[] nums) {
MyThread myThrd = new MyThread(name, nums);
myThrd.thrd.start();
return myThrd;
}
@Override
public void run() {
int sum;
System.out.println(thrd.getName() + "启动");
//这里,在sa对象上对sumArray的调用进行同步
// synchronized (sa) {
answer = sa.sumArray(a);
System.out.println(thrd.getName() + "计算的结果是:" + answer);
// }
System.out.println(thrd.getName()+"结束");
}
}
//===========================================================================================================
//创建一个拥有main函数的类
class Sync{
public static void main(String[] args) {
int[] arr = {, , , , };
MyThread myt = MyThread.createAndStart("线程1", arr);
MyThread myt1 = MyThread.createAndStart("线程2", arr);
}
}
线程2启动
线程1启动
线程1计算的结果是:22
线程2计算的结果是:22
线程1结束
线程2结束
//ps 结果是22 原因是因为有一个sleep,这样才能更客观的发现两个线程的区别
创建了两个线程,两个线程不分先后的执行一个方法,由于线程的并行特性,会发生两个线程同时进入一个方法的情况, 这时候就会可能会导致数据操作次数改变,从而直接影响结果.
有两个方法:
方法1:
在sumArray()方法上加synchronized关键字,加上这个关键字后的sumArray()学名叫做"同步方法"
public synchronized int sumArray(int[] sums) {
sum = ; //重置 / 初始化sum
for (int i = ; i < sums.length; i++) {
sum += sums[i];
try {
Thread.sleep();
} catch (InterruptedException e) {
System.out.println("线程中断");
e.printStackTrace();
}
}
return sum;
}
加上synchronized ,不管在什么样的线程情况下,可以保证每一次只能由一个线程进入这个方法,其他线程排队等待,直到当前线程执行完毕才可以进入.
方法2
使用同步语句
static SumArray sa = new SumArray();
public void run() {
int sum;
System.out.println(thrd.getName() + "启动");
synchronized (sa) {//这一段
answer = sa.sumArray(a);
System.out.println(thrd.getName() + "计算的结果是:" + answer);
}
System.out.println(thrd.getName()+"结束");
}
同步语句的基本格式:
synchronized(ref){
//方法体
}
这里的ref是被同步对象的引用,上文代码中就直接引用的一个普通对象
两种方法都可以实现方法的同步阻止多线程的环境下造成数据紊乱的情况
那么同步方法和同步语句的区别在哪呢?
虽然同步方法时实现同步的一种简单有效的方法,但这方法并不适用于所有情况,
例如:可能需要对某些不被synchronized修改的方法进行同步.在想使用有第三方创建的类,而无法访问源代码时就会出现这样的情况.
这个时候使用同步代码块
各有所需,两种用法,作用相同.
Java之多线程同步基础的更多相关文章
- Java自学-多线程 同步synchronized
Java 多线程同步 synchronized 多线程的同步问题指的是多个线程同时修改一个数据的时候,可能导致的问题 多线程的问题,又叫Concurrency 问题 步骤 1 : 演示同步问题 假设盖 ...
- Java中多线程同步类 CountDownLatch
在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...
- 【53】java的多线程同步剖析
synchronized关键字介绍: synchronized锁定的是对象,这个很重要 例子: class Sync { public synchronized void test() { Syste ...
- C#中的多线程 - 同步基础
原文:http://www.albahari.com/threading/part2.aspx 文章来源:http://blog.gkarch.com/threading/part2.html 1同步 ...
- 160407、java实现多线程同步
多线程就不说了,很好理解,同步就要说一下了.同步,指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系.所以同步的关键是多个线程对象竞争同一个共享资源. 同步分为外同步和内同步.外同步就是在外 ...
- C#中的多线程 - 同步基础 z
原文:http://www.albahari.com/threading/part2.aspx 专题:C#中的多线程 1同步概要Permalink 在第 1 部分:基础知识中,我们描述了如何在线程上启 ...
- java的多线程:线程基础
1.线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是 ...
- [Java][Android] 多线程同步-主线程等待全部子线程完毕案例
有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已! 此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情.而使用线程的话 ...
- 【java】多线程同步生产者消费者问题
package 多线程; class Producer implements Runnable{ private Data data; public Producer(Data data){ this ...
随机推荐
- 安装 jdk-8u121( jdk1.8 ) Eclipse jee neon java EE 4.6 并配置 中国科学技术大学 http://mirrors.ustc.edu.cn/eclipse/ 仓库源
官网太慢用百度网盘,打不开刷新几次试试 http://pan.baidu.com/s/1qYTUrGK#list/path=%2F 首先下载安装 jdk-8u121-windows-x64.exe ...
- Struts2中的OGNL表达式
一.OGNL表达式简介 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.所谓对象图,即以任意一个对象为根,通过OGNL可以访问 ...
- 九度OJ 1118:数制转换 (进制转换)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3873 解决:1494 题目描述: 求任意两个不同进制非负整数的转换(2进制-16进制),所给整数在long所能表达的范围之内. 不 ...
- CoreGraphics(转)
2.CoreGraphics 上面我们讲过,UIBezierPath是CoreGraphics的封装,使用它可以完成大部分的绘图操作,不过更底层的CoreGraphics更加强大. CoreGraph ...
- ps 工具栏使用
1:称动工具,快捷键是v,则选中移动工具:按shift和左键,可移动当前层移到另一层的中间对齐.如果不用sfhift键,则只是移动:alt+左键上移动,则复制层:alt+中间滚轮,则为放大和缩小. 2 ...
- window上安装rabbitMQ
win7下安装RabbitMQ http://my.oschina.net/ydsakyclguozi/blog/528835?fromerr=q7m1OxxF 前辈总结的特别详细.
- RobotFramework教程使用笔记——Selenium2Library库
selenium之前已经学习介绍过了,它是一个支持多语言.多平台.多浏览器的web自动化测试框架,在robotframework中也可以导入selenium库来进行web自动化测试.它使用seleni ...
- mac配置apache
http://www.cnblogs.com/snandy/archive/2012/11/13/2765381.html 用自带的 sudo apachectl -v sudo apachectl ...
- 使用eclipse的SVN连接码云
码云配置: 码云的项目上,启用SVN访问 eclipse的配置,不配置这个会报错
- zabbix 用户自定义监控参数添加
1. item key的添加 key可以带参数,该参数为一个数组列表,可以同时传递多个参数,key的格式如下 key -- [ parameters] -- 例如: vfs.fs.size[/] v ...