`
bo_hai
  • 浏览: 552447 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

线程同步优化实例

 
阅读更多

代码如下:

package com.bohai.thread;

public class ThreadNoSynchronized {

	public static void main(String[] args) {
		ShareData oShare = new ShareData(); // 创建,初始化ShareData对象oShare  
        ThreadDemo th1 = new ThreadDemo("Thread1", oShare); // 创建线程th1  
        ThreadDemo th2 = new ThreadDemo("Thread2", oShare); // 创建线程th2  
        th1.start(); // 启动线程th1  
        th2.start(); // 启动线程th2 
	}

}

class ShareData {  
    public static String szData = ""; // 声明,并初始化字符串数据域,作为共享数据  
  
}  
class ThreadDemo extends Thread {  
    private ShareData oShare; // 声明,并初始化ShareData 数据域  
    ThreadDemo() {  
    } // 声明,并实现ThreadDemo 构造方法  
  
    // 声明,并实现ThreadDemo 带参数的构造方法  
    ThreadDemo(String szName, ShareData oShare) {  
        super(szName); // 调用父类的构造方法  
        this.oShare = oShare; // 初始化oShare域  
    }  
    public void run() {  
        for (int i = 0; i < 10; i++) {  
            if (this.getName().equals("Thread1")) {  
            	oShare.szData = "这是第 1 个线程";  
                // 为了演示产生的问题,这里设置一次睡眠  
                try {  
                    Thread.sleep((int) Math.random() * 100); // 休眠  
                } catch (InterruptedException e) { // 捕获异常  
                }  
                System.out.println(this.getName() + ":" + oShare.szData); // 输出字符串信息  
            } else if (this.getName().equals("Thread2")) {  
            	oShare.szData = "这是第 2 个线程";  
                // 为了演示产生的问题,这里设置一次睡眠  
                try {  
                    Thread.sleep((int) Math.random() * 100); // 线程休眠  
                } catch (InterruptedException e) // 捕获异常  
                {  
                }  
                System.out.println(this.getName() + ":" + oShare.szData); // 输出字符串信息  
            }  
        }  
    }  
} 

 执行结果如下:

Thread1:这是第 2 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread1:这是第 1 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程
Thread2:这是第 2 个线程

 

从结果可以看出,这不是我们期望的结果:优化后代码如下:

package com.bohai.thread;

public class ThreadNoSynchronized {

	public static void main(String[] args) {
		ShareData oShare = new ShareData(); // 创建,初始化ShareData对象oShare  
        ThreadDemo th1 = new ThreadDemo("Thread1", oShare); // 创建线程th1  
        ThreadDemo th2 = new ThreadDemo("Thread2", oShare); // 创建线程th2  
        th1.start(); // 启动线程th1  
        th2.start(); // 启动线程th2 
	}

}

class ShareData {  
    public static String szData = ""; // 声明,并初始化字符串数据域,作为共享数据  
  
}  
class ThreadDemo extends Thread {  
    private ShareData oShare; // 声明,并初始化ShareData 数据域  
    ThreadDemo() {  
    } // 声明,并实现ThreadDemo 构造方法  
  
    // 声明,并实现ThreadDemo 带参数的构造方法  
    ThreadDemo(String szName, ShareData oShare) {  
        super(szName); // 调用父类的构造方法  
        this.oShare = oShare; // 初始化oShare域  
    }  
    public void run() {  
        for (int i = 0; i < 10; i++) {  
            if (this.getName().equals("Thread1")) {  
            	synchronized (oShare) {
            		oShare.szData = "这是第 1 个线程";  
				}
                // 为了演示产生的问题,这里设置一次睡眠  
                try {  
                    Thread.sleep((int) Math.random() * 100); // 休眠  
                } catch (InterruptedException e) { // 捕获异常  
                }  
                System.out.println(this.getName() + ":" + oShare.szData); // 输出字符串信息  
            } else if (this.getName().equals("Thread2")) {  
            	synchronized (oShare) {
            		oShare.szData = "这是第 2 个线程";  
				}
                // 为了演示产生的问题,这里设置一次睡眠  
                try {  
                    Thread.sleep((int) Math.random() * 100); // 线程休眠  
                } catch (InterruptedException e) // 捕获异常  
                {  
                }  
                System.out.println(this.getName() + ":" + oShare.szData); // 输出字符串信息  
            }  
        }  
    }  
} 

 对共享变量需要进行同步。不要在方法上使用 synchronized。

分享到:
评论
1 楼 bo_hai 2014-09-04  
对共享变量的操作有两种安全的操作方式:
1、隔离方问(ThreadLocal)
2、同步机制;(synchronized ),使用同步机制需要注意的事项有:对相同的资源需要持有相同的锁。

相关推荐

    多线程下的单例模式优化

    这是一个关于多线程下的单例模式优化代码。public class Singleton { private static Singleton instance; private Singleton (){ } public static Singleton getInstance(){ //对获取实例的方法进行同步 if...

    Java多线程优化百万级数据

    通过实例给出利用Java多线程优化读取数据库百万级别数据

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例137 使用线程局部变量实现线程同步 177 实例138 简单的线程通信 179 实例139 简单的线程死锁 180 实例140 解决线程的死锁问题 182 6.3 线程的进阶 183 实例141 使用阻塞队列实现线程同步 183 实例142 新建有...

    Java优化编程(第2版)

    4.1.1 线程同步散列表类 4.1.2 设置arraylist初始化容量 4.1.3 arraylist与linkedlist 4.2 string类与性能优化 4.2.1 字符串累加与性能优化 4.2.2 字符串的length()方法与性能优化 4.2.3 tochararray()方法与性能...

    Java性能优化

    控制资源的使用,通过线程同步来控制资源的并发访问; 控制实例的产生,以达到节约资源的目的; 控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信。 2.尽量避免随意使用静态变量 要...

    JAVA上百实例源码以及开源项目源代码

    J2ME优化压缩PNG文件 4个目标文件 内容索引:JAVA源码,综合应用,J2me游戏,PNG,图形处理  这是个J2ME控制台程序,它能剔除PNG文件中的非关键数据段,减少文件大小从而达到压缩图片的目的。而图片的质量并不会受到损失...

    mysql同步问题之Slave延迟很大优化方法

    一般而言,slave相对master延迟较大,其根本原因就是slave上的复制线程没办法真正做到并发...不过,它只能支持一个实例下多个 database 间的并发复制,并不能真正做到多表并发复制。因此在较大并发负载时,slave还是没

    DELPHI 5编程实例与技巧

    8.3 线程的同步 169 8.4 线程的优先级 170 第9章 动态链接库 176 9.1 概述 176 9.2 创建动态链接库 177 9.3 使用动态链接库 179 9.4 方法与技巧 180 9.4.1 如何调试动态链接库 180 9.4.2 在DLL中使用MessageBox代替...

    构建最高可用Oracle数据库系统 Oracle 11gR2 RAC管理、维护与性能优化

    13.1.3日志线程与联机Redo日志 13.1.4 UNDO表空间 13.2实例恢复 13.2.1 RAC的实例恢复 13.2.2实例恢复的阶段 13.3介质恢复 13.3.1介质恢复的过程 13.3.2物理坏块和逻辑坏块 13.3.3坏块的检测工具 13.3.4块...

    《Windows网络编程技术》高清PDF版+随书源码

    单机资源共享的应用编程2.1 进程间通信2.1.1 进程间通信应用实例及概念2.1.2 进程的创建与终止2.1.3 内存文件映射2.2 多线程通信2.2.1 多线程应用实例及概念2.2.2 线程的创建、挂起、激活和终止2.2.3 线程的优先级...

    WINDOWS网络编程技术.pdf

    单机资源共享的应用编程2.1 进程间通信2.1.1 进程间通信应用实例及概念2.1.2 进程的创建与终止2.1.3 内存文件映射2.2 多线程通信2.2.1 多线程应用实例及概念2.2.2 线程的创建、挂起、激活和终止2.2.3 线程的优先级...

    Java并发编程(学习笔记).xmind

    (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并在特定的同步位置交互 (3)简化异步事件的处理:服务器应用程序在接受...

    C#开发常见问题清单总结与入门常见问题.docx

    技巧10:线程同步与并发控制 技巧11:避免死锁的策略与设计模式 技巧12:线程安全编程与锁机制的正确使用 5. .NET框架高级特性 技巧13:LINQ查询表达式的高效运用 技巧14:Lambda表达式与委托的简化编程 技巧15:...

    java深度历险

    JAVA线程的同步 19 中断线程 20 参考资料 20 JAVA垃圾回收机制与引用类型 22 JAVA垃圾回收机制 22 JAVA引用类型 23 参考资料 27 JAVA泛型 28 类型擦除 28 实例分析 29 通配符与上下界 30 类型系统 31 开发自己的泛型...

    JAVA上百实例源码以及开源项目

    J2ME优化压缩PNG文件 4个目标文件 内容索引:JAVA源码,综合应用,J2me游戏,PNG,图形处理  这是个J2ME控制台程序,它能剔除PNG文件中的非关键数据段,减少文件大小从而达到压缩图片的目的。而图片的质量并不会受到损失...

Global site tag (gtag.js) - Google Analytics