多线程

  多线程是我们开发人员经常提到的一个名词。为什么会有多线程的概念呢?我们的电脑有可能会有多个cpu(或者CPU有多个内核)这就产生了多个线程。对于单个CPU来说,由于CPU运算很快,我们在电脑上运行多个软件时,每个软件在CPU上运行很短的时间就会切换成其他软件。由于来回切换的时间很短,我们感觉好像所有的程序都在同时运行,这也是多线程。多线程可以解决较多的用户访问同一个服务时压力过大的问题,可以更充分的利用计算机的性能。

多线程的问题

  多线程的好处很多,可是相应的也出现了一些问题。其中最常见的就是脏读了。我们的程序,在多个线程访问同一个共享的数据,并且出现了对数据进行修改的时候,就很有可能出现脏读的情况。比如说:我有一个用户名为:yonghu,密码为:123的数据。我有两个线程,第一个线程将用户名密码修改为:yonghu1 : 456 第二个线程负责将修改后的数据读取。并且打印。这个时候,就有可能出现这样的输出:(用户名:yonghu 密码:456)的情况,这就是多线程并发带来的问题。代码如下:

    1 package jgs_11;
2
3 public class DirtyRead {
4 private String username = "yonghu";
5 private String password = "123";
6
// public synchronized void setValue(String username, String password) {
7 public void setValue(String username, String password) {
8 this.username = username;
9 try {
10 Thread.sleep(2000);
11 } catch (Exception e) {
12 e.printStackTrace();
13 }
14 this.password = password;
15 System.out.println("setValue 最终结果:username =" + username + ", password = " + password);
16 }
17
18 public synchronized void getValue() {
19 System.out.println("getValue 最终结果:username =" + this.username + ", password = " + this.password);
20 }
21
22 public static void main(String[] args) throws Exception {
23 final DirtyRead dr = new DirtyRead();
24 Thread t1 = new Thread(new Runnable() {
25 @Override
26 public void run() {
27 dr.setValue("yonghu1", "1654");
28 }
29 });
30 t1.start();
31 Thread.sleep(1000);
32 dr.getValue();
33 }
34
35 }

  出现这种情况的原因就是两个线程的方法,修改了同一个数据导致了资源在被修改的时候产生了我们不想要的结果。这就是脏读。

synchronized关键字

  那么,如何解决这个问题呢?我们可以给这个资源加一个锁,或者给调用这个资源的方法加一个锁。在一个线程对它进行修改的时候,将资源锁住,禁止其他线程访问。等这个线程操作完成后,才允许其他线程进行操作。这样做可以避免多个线程同时操作一个资源的时候出现问题的情况,但是会出现一个线程等待另外一个线程的情况。性能肯定会降低。这个锁的代码很简单,就是想锁住谁就给它前面加个synchronized关键字。然后就可以了,但是原理却是很复杂。

  大概是这样子的:其实synchronized的锁锁的都是对象。每个对象都有个类似于标记的东西,当我们执行一段代码,发现有synchronized关键字的时候,线程就去尝试获取这个关键字的锁(将这个标记修改下内容)。如果获取成功了(如果内容为标记值为0那么将值修改为1,表示获取锁成功,如果不为0表示当前锁处于被占用状态则获取锁失败),那么就执行代码。

  关于synchronized锁的原理,博主了解的也不是特别的透彻,希望各位大神多加指导。

jgs--多线程和synchronized的更多相关文章

  1. Java多线程同步方法Synchronized和volatile

    11 同步方法  synchronized – 同时解决了有序性.可见性问题  volatile – 结果可见性问题 12 同步- synchronized synchronized可以在任意对象上加 ...

  2. java 多线程8 : synchronized锁机制 之 方法锁

    脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数 ...

  3. Java多线程-同步:synchronized 和线程通信:生产者消费者模式

    大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...

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

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

  5. Java多线程同步 synchronized 关键字的使用

    代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...

  6. 单例模式中的多线程分析synchronized

    谈到单例模式,我们立马会想到饿汉式和懒汉式加载,所谓饿汉式就是在创建类时就创建好了实例,懒汉式在获取实例时才去创建实例,即延迟加载. 饿汉式: 1 package com.bijian.study; ...

  7. 多线程并发 synchronized对象锁的控制与优化

    本文针对用户取款时多线程并发情境,进行相关多线程控制与优化的描述. 首先建立用户类UserTest.业务操作类SynchronizedTest.数据存取类DataStore,多线程测试类MultiTh ...

  8. java多线程中synchronized关键字的用法

    转自:http://www.cdtarena.com/javapx/201308/9596.html 由于同一进程内的多个线程共享内存空间,在Java中,就是共享实例,当多个线程试图同时修改某个实例的 ...

  9. 多线程编程-- part 3 多线程同步->synchronized关键字

    多线程同时访问一个资源,可以会产生不可预料的结果,所以为这个资源加锁,访问资源的第一个线程为其加锁后,其他线程便不能在使用那个资源,直到锁被解除. 举个例子: 存款1000元,能取出800的时候我就取 ...

  10. 对java多线程里Synchronized的思考

    Synchronized这个关键字在多线程里经常会出现,哪怕做到架构师级别了,在考虑并发分流时,也经常会用到它.在本文里,将通过一些代码实验来验证它究竟是"锁"什么. 在启动多个线 ...

随机推荐

  1. spring(二) AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  2. 关于commonjs,AMD,CMD之间的异同

    1.简介 随着前端业务复杂度的增加,模块化成为一个大的趋势.而在ES6还未被浏览器所支持的情况下,commonjs作为ES6中标准模块加载方案,在客服端中的支持情况并不好,现在在客服端中有2中模块化的 ...

  3. *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ViewController > setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key

    *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ViewController > ...

  4. python操作数据库之批量导入

    python操作数据库之批量导入 Python语法简洁清晰,特色之一是强制用空白符(white space)作为语句缩进. Python具有丰富和强大的库.它常被昵称为胶水语言,能够把用其他语言制作的 ...

  5. 手机自动化测试:Appium源码之api(1)

    手机自动化测试:Appium源码之api(1)   AppiumDriver getAppStrings() 默认系统语言对应的Strings.xml文件内的数据. driver.getAppStri ...

  6. 关于android混淆文件project.properties和proguard-project.txt详解

    一直不明白Android开发中的有些文件的具体作用,后来用到了,具体研究了一下,借鉴了一下网上的资料,最后总结下,方便以后查看! 老版本中有这么个文件default.properties,既然是老版本 ...

  7. Hibernate基础学习(三)—Session

    一.概述      Session接口是Hibernate向应用程序提供的操纵数据库最主要的接口,它提供了基本的保存.更新.删除和加载Java对象的方法.      Session具有一个缓存,位于缓 ...

  8. scss的初级学习随笔小计

    $white: #fff;$three: #333;$six: #666;$nine: #999;$red: #fff;$orange: #f63;$yellow: #fc0;$opcity: rgb ...

  9. MySQL元数据库——information_schema

    平时使用MySQL客户端操作数据库的同学,只要稍微留神都会发现,除了我们建的库之外,还经常看到三个数据库的影子: 1. information_schema 2. performance_schema ...

  10. 一个只有99行代码的JS流程框架

    张镇圳,腾讯Web前端高级工程师,对内部系统前端建设有多年经验,喜欢钻研捣鼓各种前端组件和框架. 最近一直在想一个问题,如何能让js代码写起来更语义化和更具有可读性. 上周末的时候突发奇想,当代码在运 ...