线程安全问题:

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

模拟线程安全问题

/**
* 启动两个线程分别打印两个名字,名字按照字符一个一个打印
*
* @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. childNodes的兼容性问题

    元素.childNodes:只读 属性 子节点列表集合 标准浏览器下:包含文本和元素类型节点,也会包含非法嵌套的子节点 非标准浏览器下:只包含元素类型节点,ie7下不会包含非法嵌套的子节点 child ...

  2. ATI显卡添加自定义分辨率

    run regedit, 浏览到这个键目录下 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video 先导出一个作为备份. 查找 DALNo ...

  3. BZOJ 4034 【HAOI2015】 T2

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...

  4. node基础01:简要介绍

    1.node vs php 优点 性能高(机制问题) 开发效率高(省了不少优化的事) 应用范围广(可以开发桌面系统,electron框架) 缺点 新,人少 中间件少 IDE不完善 2.node的劣势和 ...

  5. python 图

    class Graph(object): def __init__(self,*args,**kwargs): self.node_neighbors = {} self.visited = {} d ...

  6. Android -- Apk安装简诉

    安装涉及到如下几个目录 system/app  ​ 系统自带的应用程序,无法删除 data/app   用户程序安装的目录,有删除权限. 安装时把apk文件复制到此目录 ​ data/data  存放 ...

  7. Qt 5.2 Creator 和 vs2012 QT 插件的安装

    在QT官网下载QT http://qt-project.org/downloads 我下的是64位版本Qt 5.2.1 for Windows 64-bit vs2012插件是  Visual Stu ...

  8. DOM Element节点类型详解

    上文中我们讲解了 DOM 中最重要的节点类型之一的 Document 节点类型,本文我们继续深入,谈谈另一个重要的节点类型 Element . 1.概况 Element 类型用于表现 HTML 或 X ...

  9. 各种主流 SQLServer 迁移到 MySQL 工具对比

          我之所以会写这篇对比文章,是因为公司新产品研发真实经历过这个痛苦过程(传统基于SQL Server开发的C/S产品转为MySQL云产品).首次需要数据转换是测试环节,当时为了快速验证新研发 ...

  10. 「拉勾网」薪资调查的小爬虫,并将抓取结果保存到excel中

    学习Python也有一段时间了,各种理论知识大体上也算略知一二了,今天就进入实战演练:通过Python来编写一个拉勾网薪资调查的小爬虫. 第一步:分析网站的请求过程 我们在查看拉勾网上的招聘信息的时候 ...