线程安全问题:

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

模拟线程安全问题

/**
* 启动两个线程分别打印两个名字,名字按照字符一个一个打印
*
* @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. Maven私服Nexus3.x环境构建操作记录

    Maven介绍Apache Maven是一个创新的软件项目管理和综合工具.Maven提供了一个基于项目对象模型(POM)文件的新概念来管理项目的构建,可以从一个中心资料片管理项目构建,报告和文件.Ma ...

  2. Windows 8.1 新增控件之 Flyout

    本篇为大家介绍Flyout 控件,Flyout 属于一种轻量级交互控件,可以支持信息提示或用户交互.与传统Dialog 控件不同的是Flyout 控件可通过直接点击对话框外部区域忽略. Flyout ...

  3. 实现Linux与Windows下一致的命令行

    这其实是个非常简单的东西. 我们会写一些命令行的工具,一般跨平台的话,会用python或者perl写,比如叫foo.py,然后在Windows和Linux下调用这个脚本: Linux: foo.py ...

  4. c++多重继承小结

    如果一个类从两个不同的类里继承两个同名的成员,则需要在派生类中使用类限定符来区分他们. 即在从A和B派生出来的c类中使用a::Show()和B::Show()来区分从这两个类那里继承的show()方法 ...

  5. 【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays

    一道非常经典的题目,Median of Two Sorted Arrays.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/ ...

  6. 在SQL Server 2012中实现CDC for Oracle

    在上篇在SSIS 2012中使用CDC(数据变更捕获)中,介绍了如何在SSIS 2012中使用CDC,本文在此基础上介绍,如何通过Attunity提供的Change Data Capture Desi ...

  7. 生成短链(网址) ShortUrlLink

    建表 CREATE TABLE [dbo].[ShortUrl]( [Id] [,) NOT NULL, [LongUrl] [nvarchar]() NOT NULL, [BaseUri] [int ...

  8. Linux配置无线网卡驱动实现无线上网

    本机装Linux,需要配置的无线驱动.一般Ubuntu都集成无线驱动,基本上无线可以直接使用! 01.查看无线网卡的型号 [root@Mr-zhao software]# lspci    | gre ...

  9. PotPlayer为播放而生的专业播放器

    韩国,比较牛逼的视频播放器.专注与本地视频播放,值得拥有.... 免费下载:http://yunpan.cn/cmZ5ELC6DTI8Y  访问密码 4bf1

  10. 在nginx中配置如何防止直接用ip访问服务器web server及server_name特性讲解

    看了很多nginx的配置,好像都忽略了ip直接访问web的问题,不利于SEO优化,所以我们希望可以避免直接用IP访问网站,而是域名访问,具体怎么做呢,看下面. 官方文档中提供的方法: If you d ...