文档章节

一、加互斥锁Synchronized,保证线程的原子性(多个线程访问的对象的非static方法)

LYQ1990
 LYQ1990
发布于 2016/05/09 12:56
字数 437
阅读 236
收藏 4

 

多个线程同时访问同一个资源----在同一个资源上,加互斥锁Synchronized,保证线程的原子性,在第一个线程代码全部执行结束,再开始执行第二个线程

说明:Outputer类只new了一次线程一和线程二用的是同一个outputer,锁的是同一个对象。否则即使加锁,也无法达到原子性。

 

********************************************************************

线程一:用Outputer类的output方法,打印“张三吃饭”

线程二:用Outputer类的output方法,打印“李四打游戏”

****************如果不加线程锁,会出现类似下面的结果**************

张三李四打游戏

吃饭

***********************解决方法如下********************************

方法一:在Outputer类的output方法,用this给类对象加锁synchronized (this)

 

注明:【不行的方法: 给output方法的参数加锁synchronized (name),第一个线程的name和第二个线程的name不是同一个】

方法二:在Outputer类,定义一个变量,给这个变量加锁

 class Outputer{

    String tempSysch="";

    public void output(String name){

     synchronized (tempSysch) {}

  }

方法三:在Outputer类的output方法上加锁

public synchronized void output(String name) {}

******************************************************************

 

--------------------------------代码如下----------------------

public class TraditionalThreadSynchronized {

  public static void main(String[] args) {
    TraditionalThreadSynchronized th = new TraditionalThreadSynchronized();
    th.init();
  }

  private void init() {
    final Outputer outputer = new Outputer();
    // 线程一:用Outputer类打印“张三吃饭”
    new Thread(new Runnable() {
      @Override
      public void run() {
        while (true) {
          outputer.output("张三吃饭");
        }
      }
    }).start();
    // 线程二:用Outputer类打印“李四打游戏”
    new Thread(new Runnable() {
      @Override
      public void run() {
        while (true) {
          outputer.output2("李四打游戏");
        }
      }
    }).start();
  }

  // Outputer类
  class Outputer {
    // synchronized修饰对象
    public void output(String name) {
      synchronized (this) {
        // synchronized (name) {
        for (int i = 0; i < name.length(); i++) {
          System.out.print(name.charAt(i));
        }
        System.out.println();
      }
    }

    // synchronized修饰方法
    public synchronized void output2(String name) {
      for (int i = 0; i < name.length(); i++) {
        System.out.print(name.charAt(i));
      }
      System.out.println();
    }
  }
}

© 著作权归作者所有

共有 人打赏支持
LYQ1990
粉丝 6
博文 238
码字总数 206220
作品 0
东城
多线程编程学习二(对象及变量的并发访问).

一、概念 非线程安全:会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是"脏读",也就是取到的数据其实是被更改过的. 线程安全:获得的实例变量的值是经过同步处理的...

jmcui
2017/09/09
0
0
java同步synchronized详解

synchronized可以修饰代码块也可以修饰方法,还可以作用于静态方法,类和某个实例。 每个对象都有一把锁,当多个线程同时访问共享资源的时候,需要用到synchronized,synchronized分为代码块...

camillelm
2015/12/08
266
0
Synchronized

1、JavaSE 1.6 之前都认为synchronized是重量级锁,但是1.6进行了各种优化操作,所以并不是想象中那么重了,虽然synchronized的地方使用Lock都能实现,但是synchronized用处还是很广泛。 2、...

learn_more
2016/08/27
25
0
Java 多线程编程核心技术 笔记

外练互斥,内修可见。 1:currentThread() 方法可返回代码正在被哪个线程调用的信息 使用方法:Thread.currentThread.getName() 2:isAlive() 功能是判断当前线程是否处于活动状态 使用方法:T...

西瓜1994
10/12
0
0
JAVA基础知识系列---进程、线程安全

1.1 临界区 保证在某一时刻只有一个线程能访问数据的简便方法,在任意时刻只允许一个线程对资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后,其他所有试图访问临界...

glmapper
2017/10/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringData JPA 在解析实体类字段时驼峰自动添加下划线问题

SpringData JPA 使用的默认命名策略是: ImprovedNamingStrategy 。用下划线转换驼峰名,如 authorId ,转换成 author_id 。这样就遇到了一个问题:实体中驼峰命名的列名转换成下划线后,在M...

Jacktanger
18分钟前
0
0
Android JNI开发系列(十)JNI访问 Java 实例变量和静态变量

JNI访问 Java 实例变量和静态变量 Java 中的实例变量和静态变量,在本地代码中如何来访问和修改。静态变量也称为类变量(属性),在所有实例对象中共享同一份数据,可以直接通过类名.变量名来...

蔡小鹏
23分钟前
0
0
jsapi4加载的首个图层的范围被默认作为地图范围,且不能修改的解决

在map加载的第一个图层的图层范围(fullExtent),会被默认设置为map的全图范围,且不能更改,从一般地图控件角度来说,应该有fullExtent属性,作为地图的全图范围,但很遗憾jsapi4.9还没有 ...

canneljls
24分钟前
0
0
JSON.stringify()

JSON.parse()与JSON.stringify()的区别 JSON.parse()【从一个字符串中解析出json对象】 例子: //定义一个字符串 var data='{"name":"goatling"}' //解析对象 JSON.parse(data) 结果是: na...

废柴
24分钟前
0
0
HashSet

前言 Set的实现类都是基于Map来实现的(HashSet是通过HashMap实现的)。 构造图如下: 蓝色线条:继承 绿色线条:接口实现 正文 对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保...

狼王黄师傅
26分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部