java学习的道路上呢总有一些麻烦的东西需要花费一些时间去理解,比如个人认为不好搞的多线程.

线程是并列运行的

因为是并列运行,所以有时候会发生资源抢占,从而导致参数变化;

比如酱紫

  1. package seer.线程;
  2.  
  3. public class SumArray {
  4. private int sum;
  5.  
  6. //在这个地方sumArry()没有被同步 没有加sync...
  7. public int sumArray(int[] sums) {
  8. sum = ; //重置 初始化sum
  9. for (int i = ; i < sums.length; i++) {
  10. sum += sums[i];
  11. try {
  12. Thread.sleep(); //发生任务切换时,有意允许切换的发生(如果加了synchronized就绝对不可能发生了.)
  13. } catch (InterruptedException e) {
  14. System.out.println("线程中断");
  15. e.printStackTrace();
  16. }
  17. }
  18. return sum;
  19. }
  20. }
  21. //===========================================================================================================
  22.  
  23. class MyThread implements Runnable {
  24. Thread thrd;
  25. static SumArray sa = new SumArray();
  26. int[] a;
  27. int answer;
  28.  
  29. //构造一个线程
  30. public MyThread(String name, int[] nums) {
  31. thrd = new Thread(this, name);
  32. a = nums;
  33. }
  34.  
  35. //创建一个工厂方法用来创建和启动线程
  36. public static MyThread createAndStart(String name, int[] nums) {
  37. MyThread myThrd = new MyThread(name, nums);
  38. myThrd.thrd.start();
  39. return myThrd;
  40. }
  41.  
  42. @Override
  43. public void run() {
  44. int sum;
  45. System.out.println(thrd.getName() + "启动");
  46. //这里,在sa对象上对sumArray的调用进行同步
  47. // synchronized (sa) {
  48. answer = sa.sumArray(a);
  49. System.out.println(thrd.getName() + "计算的结果是:" + answer);
  50. // }
  51. System.out.println(thrd.getName()+"结束");
  52. }
  53. }
  54.  
  55. //===========================================================================================================
  56. //创建一个拥有main函数的类
  57. class Sync{
  58. public static void main(String[] args) {
  59. int[] arr = {, , , , };
  60. MyThread myt = MyThread.createAndStart("线程1", arr);
  61. MyThread myt1 = MyThread.createAndStart("线程2", arr);
  62.  
  63. }
  64. }
  65.  

线程2启动
线程1启动
线程1计算的结果是:22
线程2计算的结果是:22
线程1结束
线程2结束

  1. //ps 结果是22 原因是因为有一个sleep,这样才能更客观的发现两个线程的区别

创建了两个线程,两个线程不分先后的执行一个方法,由于线程的并行特性,会发生两个线程同时进入一个方法的情况, 这时候就会可能会导致数据操作次数改变,从而直接影响结果.

有两个方法:

  方法1: 

    在sumArray()方法上加synchronized关键字,加上这个关键字后的sumArray()学名叫做"同步方法"

  1. public synchronized int sumArray(int[] sums) {
  2. sum = ; //重置 / 初始化sum
  3. for (int i = ; i < sums.length; i++) {
  4. sum += sums[i];
  5. try {
  6. Thread.sleep();
  7. } catch (InterruptedException e) {
  8. System.out.println("线程中断");
  9. e.printStackTrace();
  10. }
  11. }
  12. return sum;
  13. }

  加上synchronized  ,不管在什么样的线程情况下,可以保证每一次只能由一个线程进入这个方法,其他线程排队等待,直到当前线程执行完毕才可以进入.

    方法2

    使用同步语句

  1. static SumArray sa = new SumArray();
  1. public void run() {
  2. int sum;
  3. System.out.println(thrd.getName() + "启动");
  4.  
  5. synchronized (sa) {//这一段
  6. answer = sa.sumArray(a);
  7. System.out.println(thrd.getName() + "计算的结果是:" + answer);
  8. }
  9. System.out.println(thrd.getName()+"结束");
  10. }

    同步语句的基本格式:

      synchronized(ref){

        //方法体

      }

     这里的ref是被同步对象的引用,上文代码中就直接引用的一个普通对象

  两种方法都可以实现方法的同步阻止多线程的环境下造成数据紊乱的情况

  那么同步方法和同步语句的区别在哪呢?

  虽然同步方法时实现同步的一种简单有效的方法,但这方法并不适用于所有情况,

  例如:可能需要对某些不被synchronized修改的方法进行同步.在想使用有第三方创建的类,而无法访问源代码时就会出现这样的情况.

  这个时候使用同步代码块

  各有所需,两种用法,作用相同.

  

Java之多线程同步基础的更多相关文章

  1. Java自学-多线程 同步synchronized

    Java 多线程同步 synchronized 多线程的同步问题指的是多个线程同时修改一个数据的时候,可能导致的问题 多线程的问题,又叫Concurrency 问题 步骤 1 : 演示同步问题 假设盖 ...

  2. Java中多线程同步类 CountDownLatch

    在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...

  3. 【53】java的多线程同步剖析

    synchronized关键字介绍: synchronized锁定的是对象,这个很重要 例子: class Sync { public synchronized void test() { Syste ...

  4. C#中的多线程 - 同步基础

    原文:http://www.albahari.com/threading/part2.aspx 文章来源:http://blog.gkarch.com/threading/part2.html 1同步 ...

  5. 160407、java实现多线程同步

    多线程就不说了,很好理解,同步就要说一下了.同步,指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系.所以同步的关键是多个线程对象竞争同一个共享资源. 同步分为外同步和内同步.外同步就是在外 ...

  6. C#中的多线程 - 同步基础 z

    原文:http://www.albahari.com/threading/part2.aspx 专题:C#中的多线程 1同步概要Permalink 在第 1 部分:基础知识中,我们描述了如何在线程上启 ...

  7. java的多线程:线程基础

    1.线程与进程区别 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是 ...

  8. [Java][Android] 多线程同步-主线程等待全部子线程完毕案例

    有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已! 此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情.而使用线程的话 ...

  9. 【java】多线程同步生产者消费者问题

    package 多线程; class Producer implements Runnable{ private Data data; public Producer(Data data){ this ...

随机推荐

  1. win10获取注册表权限

    1.cmd中输入regedit打开注册表 2.在需要的注册表项中右键选择“权限”

  2. FormsAuthentication 在asp.net MVC中的应用

    说明:开发环境 vs2012 asp.net mvc4 c# 项目结构: 1.开发步骤 1.1 创建项目 打开vs2012 开发环境 “文件”--“新建”--“项目” 选择asp.net mvc项目类 ...

  3. Java Message Service

    en.wikipedia.org/wiki/Java_Message_Service Messaging is a form of loosely coupled distributed commun ...

  4. Node中的Socket.IO 简单Demo及说明

    注:下面Demo的Server和Client都是纯后端. 并没有web页面. Server端代码: var express = require('express'); var app = expres ...

  5. spawn类expect方法详解

    本文我们将介绍spawn类的基本方法expect方法,这个方法是用来匹配返回的结果,这个返回的结果是指子程序的返回结果,同时会将匹配的相关信息保存在spawn类的相关属性中. 基本属性包括三个,第一个 ...

  6. php遍历统计文件目录和文件

    function total($dirname, &$dirnum, &$filenum){ $dir=opendir($dirname); readdir($dir)."& ...

  7. async函数学习笔记

    含义 async函数是什么?一句话,它就是Generator函数的语法糖. const fs = require('fs') const readFile = function(fileName){ ...

  8. MVC vs MVP vs MVVM

    一.MVC MVC模式的意思是,软件可以分成三个部分. 视图(View):用户界面. 控制器(Controller):业务逻辑 模型(Model):数据保存 各部分之间的通信方式如下. View 传送 ...

  9. HDU3065 病毒侵袭持续中 —— AC自动机

    题目链接:https://vjudge.net/problem/HDU-3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

  10. <ZZ>linux yum命令详解

    http://www.cnblogs.com/chuncn/archive/2010/10/17/1853915.html yum(全称为 Yellow dog Updater, Modified)是 ...