Java多线程与并发库高级应用-传统线程互斥技术
线程安全问题:
多个线程操作同一份数据的时候,有可能会出现线程安全问题。可以用银行转账来解释。
模拟线程安全问题
/**
* 启动两个线程分别打印两个名字,名字按照字符一个一个打印
*
* @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多线程与并发库高级应用-传统线程互斥技术的更多相关文章
- Java多线程与并发库高级应用-传统线程机制回顾
		1.传统线程机制的回顾 1.1创建线程的两种传统方式 在Thread子类覆盖的run方法中编写运行代码 // 1.使用子类,把代码放到子类的run()中运行 Thread thread = new T ... 
- Java多线程与并发库高级应用-传统线程同步通信技术
		面试题: 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着又 主线程循环100次,如此循环50次,请写出程序 /** * 子线程循环10次,接着主线程循环100次,接着又回到 ... 
- Java多线程与并发库高级应用-java5线程并发库
		java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ... 
- Java多线程与并发库高级应用-传统定时器技术回顾
		传统定时器技术回顾(jdk1.5以前) public class TraditionalTimerTest { static int count = 0; public static void mai ... 
- 【Java多线程与并发库】4.传统线程同步通信技术
		我们先通过一道面试题来了解传统的线程同步通信. 题目:子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次,请写出程序. 我没有看答案, ... 
- Java多线程与并发库高级应用-工具类介绍
		java.util.concurrent.Lock 1.Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互 ... 
- Java多线程与并发库高级应用-同步集合
		ArrayBlockingQueue LinkedBlockingQueue 数组是连续的一片内存 链表是不连续的一片内存 传统方式下用Collections工具类提供的synchronizedCo ... 
- Java多线程与并发库高级应用-Callable与Future的应用
		Callable这种任务可以返回结果,返回的结果可以由Future去拿 >Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的. >Completion ... 
- Java多线程与并发库高级应用-线程池
		线程池 线程池的思想 线程池的概念与Executors类的应用 > 创建固定大小的线程池 > 创建缓存线程池 > 创建单一线程池(如何实现线程死掉后重新启动?) 关闭线程池 > ... 
随机推荐
- 58种jQuery模拟CSS3过渡页面切换特效
			演示网址 http://www.htmleaf.com/Demo/201503251573.html 点击下载 
- python环境下载地址
			python: https://www.python.org/downloads/ mysqlyog: http://down.liangchan.net/Webyog%20SQLyog%20Ulti ... 
- Padrino 生成器指南
			英文版出处:http://www.padrinorb.com/guides/generators Padrino提供了用于快速创建应用的生成器,其优势在于构建推荐的Padrino应用结构.自动生成罗列 ... 
- noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T01——T10
			T01 矩阵交换行 描述 给定一个5*5的矩阵(数学上,一个r×c的矩阵是一个由r行c列元素排列成的矩形阵列),将第n行和第m行交换,输出交换后的结果. 输入 输入共6行,前5行为矩阵的每一行元素,元 ... 
- jboss EAP 6.2 + Message Drive Bean(MDB)  整合IBM Webshpere MQ 7.5
			上一篇我们知道了消息驱动Bean的基本用法,实际大型分布式企业应用中,往往会采用高性能的商业Queue产品,比如IBM Webshpere MQ(目前最新版本是7.5 ),下面讲解下如何在Jboss ... 
- 从Hadoop Summit 2016看大数据行业与Hadoop的发展
			前言: 好吧我承认已经有四年多没有更新博客了.... 在这四年中发生了很多事情,换了工作,换了工作的方向.在工作的第一年的时候接触机器学习,从那之后的一年非常狂热的学习机器学习的相关技术,也写了一些自 ... 
- 排序图解:js排序算法实现
			之前写过js实现数组去重, 今天继续研究数组: 排序算法实现. 排序是数据结构主要内容,并不限于语言主要在于思想:大学曾经用C语言研究过一段时间的排序实现, 这段时间有空用JS再将排序知识点熟悉一遍. ... 
- <实训|第十天>从底层解释一下U盘内存为什么变小的原因附数据恢复的基本原理
			[root@localhost~]#序言 我们平时不论是买一个U盘硬盘,或者自己在电脑上创建一个分区,大小总是比我们创建的要小一点,有些人会说,这个正常啊,是因为厂家规定的1M=1000k,真正的是1 ... 
- Mecanim动画系统 制作流程
- 如何采集QQ群中所有成员QQ号码
			安装Google Chrome浏览器 安装Google插件:Regex Scraper 在群成员页面点击Regex 插件, 粘贴上这个代码 text_overflow">([\S\s] ... 
