线程安全问题:

  多个线程操作同一份数据的时候,有可能会出现线程安全问题。可以用银行转账来解释。

模拟线程安全问题

/**
* 启动两个线程分别打印两个名字,名字按照字符一个一个打印
*
* @author Administrator
*
*/
public class TraditionalThreadSynchronized { public static void main(String[] args) {
new TraditionalThreadSynchronized().init();
} public void init() {
final Outputer outputer = new Outputer();// 内部类访问成员外部变量需要加final
new Thread(new Runnable() { @Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("aaaaa");
}
}
}).start(); new Thread(new Runnable() { @Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("bbb");
}
}
}).start();
} class Outputer {
public void output(String name) {
int len = name.length();
synchronized(this){ //使用静态代码块进行同步
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
System.out.print(c);
}
}
System.out.println();
}
} }

 

 以上涉及两个问题:

  内部类中使用外部类的成员变量需要加final 

  静态方法中不能 new 内部类的实例对象,why?

    内部类的重要特点,由于内部类可以访问外部类的成员变量,意味着外部类有了实例对象,静态方法执行时有不一定有外部类的实例对象初始化。所以互相矛盾。

以上代码还可以有一种写法

class Outputer {
public synchronized void output(String name) {
int len = name.length();
// synchronized(this){ //使用静态代码块进行同步
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
System.out.print(c);
}
// }
System.out.println();
}
}

 直接将synchronized写法方法声明中,使用静态方法方式,内部使用的对象还是this

static class Outputer {
public void output(String name) {
int len = name.length();
synchronized(Outputer.class){ //使用同步代码块进行同步 要想使output与output3进行同步,这里就不能使用this了,可以使用类的字节码
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
System.out.print(c);
}
}
System.out.println();
}
public synchronized void output2(String name) { //同步方法
int len = name.length();
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
System.out.print(c);
}
System.out.println();
}
public static synchronized void output3(String name) { //同步方法
int len = name.length();
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
System.out.print(c);
}
System.out.println();
}
}

synchronized关键字后边是要检查一把锁对象, 要在某段代码上实现同步,必须使用同一把锁挡住这些线程,不同锁是挡不住的。

静态方法中不能跟this关联,跟类的字节码进行关联

Java多线程与并发库高级应用-传统线程互斥技术的更多相关文章

  1. Java多线程与并发库高级应用-传统线程机制回顾

    1.传统线程机制的回顾 1.1创建线程的两种传统方式 在Thread子类覆盖的run方法中编写运行代码 // 1.使用子类,把代码放到子类的run()中运行 Thread thread = new T ...

  2. Java多线程与并发库高级应用-传统线程同步通信技术

    面试题: 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着又 主线程循环100次,如此循环50次,请写出程序 /** * 子线程循环10次,接着主线程循环100次,接着又回到 ...

  3. Java多线程与并发库高级应用-java5线程并发库

    java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ...

  4. Java多线程与并发库高级应用-传统定时器技术回顾

    传统定时器技术回顾(jdk1.5以前) public class TraditionalTimerTest { static int count = 0; public static void mai ...

  5. 【Java多线程与并发库】4.传统线程同步通信技术

    我们先通过一道面试题来了解传统的线程同步通信. 题目:子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次,请写出程序. 我没有看答案, ...

  6. Java多线程与并发库高级应用-工具类介绍

    java.util.concurrent.Lock 1.Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互 ...

  7. Java多线程与并发库高级应用-同步集合

    ArrayBlockingQueue LinkedBlockingQueue 数组是连续的一片内存 链表是不连续的一片内存  传统方式下用Collections工具类提供的synchronizedCo ...

  8. Java多线程与并发库高级应用-Callable与Future的应用

    Callable这种任务可以返回结果,返回的结果可以由Future去拿 >Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的. >Completion ...

  9. Java多线程与并发库高级应用-线程池

    线程池 线程池的思想  线程池的概念与Executors类的应用 > 创建固定大小的线程池 > 创建缓存线程池 > 创建单一线程池(如何实现线程死掉后重新启动?) 关闭线程池 > ...

随机推荐

  1. 58种jQuery模拟CSS3过渡页面切换特效

    演示网址 http://www.htmleaf.com/Demo/201503251573.html 点击下载

  2. python环境下载地址

    python: https://www.python.org/downloads/ mysqlyog: http://down.liangchan.net/Webyog%20SQLyog%20Ulti ...

  3. Padrino 生成器指南

    英文版出处:http://www.padrinorb.com/guides/generators Padrino提供了用于快速创建应用的生成器,其优势在于构建推荐的Padrino应用结构.自动生成罗列 ...

  4. noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T01——T10

    T01 矩阵交换行 描述 给定一个5*5的矩阵(数学上,一个r×c的矩阵是一个由r行c列元素排列成的矩形阵列),将第n行和第m行交换,输出交换后的结果. 输入 输入共6行,前5行为矩阵的每一行元素,元 ...

  5. jboss EAP 6.2 + Message Drive Bean(MDB) 整合IBM Webshpere MQ 7.5

    上一篇我们知道了消息驱动Bean的基本用法,实际大型分布式企业应用中,往往会采用高性能的商业Queue产品,比如IBM Webshpere MQ(目前最新版本是7.5 ),下面讲解下如何在Jboss ...

  6. 从Hadoop Summit 2016看大数据行业与Hadoop的发展

    前言: 好吧我承认已经有四年多没有更新博客了.... 在这四年中发生了很多事情,换了工作,换了工作的方向.在工作的第一年的时候接触机器学习,从那之后的一年非常狂热的学习机器学习的相关技术,也写了一些自 ...

  7. 排序图解:js排序算法实现

    之前写过js实现数组去重, 今天继续研究数组: 排序算法实现. 排序是数据结构主要内容,并不限于语言主要在于思想:大学曾经用C语言研究过一段时间的排序实现, 这段时间有空用JS再将排序知识点熟悉一遍. ...

  8. <实训|第十天>从底层解释一下U盘内存为什么变小的原因附数据恢复的基本原理

    [root@localhost~]#序言 我们平时不论是买一个U盘硬盘,或者自己在电脑上创建一个分区,大小总是比我们创建的要小一点,有些人会说,这个正常啊,是因为厂家规定的1M=1000k,真正的是1 ...

  9. Mecanim动画系统 制作流程

  10. 如何采集QQ群中所有成员QQ号码

    安装Google Chrome浏览器 安装Google插件:Regex Scraper 在群成员页面点击Regex 插件, 粘贴上这个代码 text_overflow">([\S\s] ...