1、加锁不正确导致数据不一致:m1执行过程中,m2(未加synchronized)可以执行,因为m2不用获得锁就可以执行

 1 public class TT implements Runnable {
2 int b = 100;
3
4 public synchronized void m1() throws Exception {
5 b = 1000;
6 System.out.println("in m1() before sleep,b="+b);
7 Thread.sleep(5000);
8 System.out.println("in m1() after sleep,b="+b);
9 }
10
11 public void m2() {
12 //public synchronized void m2() throws Exception {
13 b = 199;
14 System.out.println("in m2(),b="+b);
15 }
16
17 public void run() {
18 try {
19 m1();
20 } catch (Exception e) {
21 e.printStackTrace();
22 }
23 }
24
25 public static void main(String[] args) throws Exception {
26 TT tt = new TT();
27 System.out.println("in main() just after new TT(),b=" + tt.b);
28 Thread t = new Thread(tt);
29 t.start();
30
31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值
32 tt.m2(); // 主线程执行m2
33
34 System.out.println("in main() last,b=" + tt.b);
35 }
36 }

结果:

D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m2(),b=199
in main() last,b=199
in m1() after sleep,b=199  //main线程先于t线程结束吗?

说明:锁定当前对象 只是针对synchronized 这段话,另外的线程完全有可能访问没有锁定的方法(即不带synchronized 的方法)

问题:要保证对资源b的正确访问,需要考虑所有访问b的所有方法,是否需要加同步:加了同步效率可能变低、不加同步可能会出现数据不一致

问题:main线程先于t线程结束吗?

解答:会,main方法即使执行完最后的语句,JVM也不会结束该程序,要等到主线程中的所有其它线程都结束之后,才结束该JAVA应用程序

2、解决上述访问资源b,数据不一致的问题:把所有访问b的方法加锁,m1执行过程,m2一定执行不了,执行m2时必须要得到当前对象的锁才能执行

 1 public class TT implements Runnable {
2 int b = 100;
3
4 public synchronized void m1() throws Exception {
5 b = 1000;
6 System.out.println("in m1() before sleep,b="+b);
7 Thread.sleep(5000);
8 System.out.println("in m1() after sleep,b="+b);
9 }
10
11 public synchronized void m2() {
12 //public synchronized void m2() throws Exception {
13 b = 199;
14 System.out.println("in m2(),b="+b);
15 }
16
17 public void run() {
18 try {
19 m1();
20 } catch (Exception e) {
21 e.printStackTrace();
22 }
23 }
24
25 public static void main(String[] args) throws Exception {
26 TT tt = new TT();
27 System.out.println("in main() just after new TT(),b=" + tt.b);
28 Thread t = new Thread(tt);
29 t.start();
30
31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值
32 tt.m2();
33
34 System.out.println("in main() last,b=" + tt.b);
35 }
36 }

结果:

D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m1() after sleep,b=1000  //m1执行完了才会执行m2
in m2(),b=199
in main() last,b=199

举例:

如何加锁:——设定同步对象时较麻烦
数据库中的某一个记录,可以改、也可以读,一般情况下哪个方法应该加锁?
(1)读:允许多个线程同时读
(2)改:要加synchronized ,不允许两个线程同时改

JAVA多线程(3)——如何加锁的更多相关文章

  1. java多线程(五)-访问共享资源以及加锁机制(synchronized,lock,voliate)

    对于单线程的顺序编程而言,每次只做一件事情,其享有的资源不会产生什么冲突,但是对于多线程编程,这就是一个重要问题了,比如打印机的打印工作,如果两个线程都同时进行打印工作,那这就会产生混乱了.再比如说, ...

  2. Java 多线程加锁的方式总结及对比(转载)

    转自https://blog.csdn.net/u010842515/article/details/67634813 参考博文:http://www.cnblogs.com/handsomeye/p ...

  3. java多线程加锁是对谁加锁?

    1.java多线程加锁是对谁加锁? 答:当然是对共享资源加锁啊,对谁进行访问修改,就对象进行加锁.以便使多线程按序访问此共享对象 比如: 在具体的Java代码中需要完成一下两个操作:把竞争访问的资源类 ...

  4. 40个Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  5. Java多线程基础知识篇

    这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...

  6. 第一章 Java多线程技能

    1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...

  7. java从基础知识(十)java多线程(下)

    首先介绍可见性.原子性.有序性.重排序这几个概念 原子性:即一个操作或多个操作要么全部执行并且执行的过程不会被任何因素打断,要么都不执行. 可见性:一个线程对共享变量值的修改,能够及时地被其它线程看到 ...

  8. Java多线程-并发容器

    Java多线程-并发容器 在Java1.5之后,通过几个并发容器类来改进同步容器类,同步容器类是通过将容器的状态串行访问,从而实现它们的线程安全的,这样做会消弱了并发性,当多个线程并发的竞争容器锁的时 ...

  9. Java多线程编程核心技术---学习分享

    继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...

  10. Java多线程总结之线程安全队列Queue

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非 ...

随机推荐

  1. adb如何做Android ui自动化(这一篇就够了)

    一.简介 我们都知道在做Android ui自动化的时候用的是appium,环境搭建贼难受.如果我们在工作中遇到需要实现简单的自动化功能,可以直接使用adb来完成,无需去搭建繁琐的appium.ADB ...

  2. SpringBoot 使用 Sa-Token 实现账号封禁、分类封禁、阶梯封禁

    一.需求分析 之前的章节中,我们学习了 踢人下线 和 强制注销 功能,用于清退违规账号.在部分场景下,我们还需要将其 账号封禁,以防止其再次登录. Sa-Token 是一个轻量级 java 权限认证框 ...

  3. 1.简述Hibernate的工作原理。

    (1).首先,Configuration读取Hibernate的配置文件和映射文件中的信息,即加载配置文件和映射文件,并通过Hibernate配置文件生成一个多线程的SessionFactory对象: ...

  4. ubuntu 20.04 网络配置

    参考链接:ubuntu 20.04 网络配置 网络配置文件目录:/etc/netplan/ 配置实例 # 静态 network: version: 2 ethernets: ens33: addres ...

  5. Bash 内建命令

    官方文档 Bash内建命令 查看命令是否为Bash内建命令

  6. javascript中一些难以理解的专有名词 1(也不是很专有)

    变量提升 变量提升:是指js代码执行过程中,js引擎把变量的声明和函数的声明提升到代码的开头的"行为". 变量和函数在代码里的位置是不会变的,而是在编译阶段被js引擎放入内存中. ...

  7. 【hack】浅浅说说自己构造hack的一些逻辑~

    怎么说呢,相信很多考过竞赛的同学都会在平时的练习/考试中遭遇过100分但没有AC的情况,结果一看评测结果:subtask的数据点没过! 这时候就是遇到hack数据了,如果被这类数据卡住,说明你的代码可 ...

  8. Blazor前后端框架Known-V1.2.9

    V1.2.9 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Gith ...

  9. [glibc2.23源码]阅读源码&调试,找出free_hook-0x13分配失败的原因

    0x00 写在前面 发freebuf了:https://www.freebuf.com/articles/endpoint/373258.html 本次阅读源码是本人第一次,算是一个全新的开始.本次看 ...

  10. 使用DWS集群,用户被锁定如何解锁

    本文分享自华为云社区<[如何保证你的DWS数据更安全]使用DWS集群,用户被锁定如何解锁?>,作者:Shirley_Dou . 一.管理员用户被锁定,怎么破?gsql: FATAL: Th ...