`
clq9761
  • 浏览: 593252 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

JAVA多线程事例参考(一)

 
阅读更多

一. Java多线程安全问题,模拟银行存款

/**
 * 
 *银行账户对象,存取款操作
 *
 */
public class Account {
	String name;
    float amount;        
    public Account(String name, float amount) {
        this.name = name;
        this.amount = amount;
    }
    // 存款
    public  void deposit(float amt) {
        float tmp = amount;
        tmp += amt;        
        try {
            Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
        } catch (InterruptedException e) {
            // ignore
        }        
        amount = tmp;
    }
    // 取款
    public  void withdraw(float amt) {
        float tmp = amount;
        tmp -= amt;
        try {
            Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
        } catch (InterruptedException e) {
            // ignore
        } 
        amount = tmp;
    }
    public float getBalance() {
        return amount;
    }
}

 

/**
 * 
 * 多线程模拟银行存取款,如果没有采取同步,就会出现多线程安全问题,
 * 则最终的银行账户会出现金额不一致的情况。
 *
 */
public class AccountTest {

	private static int NUM_OF_THREAD = 1000;
    static Thread[] threads = new Thread[NUM_OF_THREAD];
    
    public static void main(String[] args){
        final Account acc = new Account("John", 1000.0f);
        for (int i = 0; i< NUM_OF_THREAD; i++) {
            threads[i] = new Thread(new Runnable() {
                public void run() {
                        acc.deposit(100.0f);
                        acc.withdraw(100.0f);
                }
            });
            threads[i].start();
        }

        for (int i=0; i<NUM_OF_THREAD; i++){
            try {
                threads[i].join(); //等待所有线程运行结束
            } catch (InterruptedException e) {
                // ignore
            }
        }
        System.out.println("Finally, John's balance is:" + acc.getBalance());
    }
}

 

二、Java多线程之synchronized

/**
 * 
 * synchronized中同步的对象必须是多线程中访问的同一个对象,否则达不到同步效果,
 * 也可用synchronized(this)代表当前对象。
 * 如果为synchronized(name)则达不到同步效果。
 *
 */
public class Foo extends Thread {
	private int val;	
	// 通过对公共对象静态变量加锁
	private static Object lock = new Object();
	public Foo(int v) {
		val = v;
	}	
	// 交叉输出(1,3)
	public synchronized void printVal1(int v) {
			while(true){
				System.out.println(v);
			}
	}	
	// 类同步,实现printVal是断面,输出只能是1或者只能是3而不能是两者同时出现
	public void printVal2(int v) 
	{ 
		synchronized(Foo.class) {
			while(true){
				System.out.println(v);
			}
		} 
	} 	
	// 同步的一般原理是应该尽量减小同步的粒度以到达更好的性能,比类同步(printVal2)效果更忧
	public void printVal3(int v) 
	{ 
		synchronized(lock) {
			while(true){
				System.out.println(v);
			}
		} 
	}	
	public void run() {
//		printVal1(val);
//		printVal2(val);
		printVal3(val);
	}
}

 

public class FooTest {	
	public static void main(String args[]){
		Foo f1 = new Foo(1); 
		f1.start(); 
		Foo f2 = new Foo(3);
		f2.start(); 
	}
}

 

三. Java多线程之ThreadLocal

   事例一:

/**
 * 
 *在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻
 *只有一个线程对共享变量进行操作。但在有些情况下,synchronized不能保证多线程对共享变量的正确读写。
 *对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”
 *的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,
 *因此可以同时访问而互不影响。
 */
public class QuerySvc {

	private String sql;
	private static ThreadLocal<String> sqlHolder = new ThreadLocal<String>();

	public QuerySvc() {
	}	
	
	/**
	 * 从运行结果可以看出sql变量中值不能保证在execute中值和set设置的值一样, 在web应用中就表现
	 * 为一个用户查询的结果不是自己的查询条件返回的结果,而是另一个用户查询条件的结果;	 
	 * 而ThreadLocal中的值总是和set中设置的值一样,这样通过使用ThreadLocal获得了线程安全性。 
	 */	
	public void execute() {
		System.out.println("Thread " + Thread.currentThread().getId()
				+ " Sql is " + sql);
		System.out.println("Thread " + Thread.currentThread().getId()
				+ " Thread Local variable Sql is " + sqlHolder.get());
	}
	public String getSql() {
		return sql;
	}
	public void setSql(String sql) {
		this.sql = sql;
		sqlHolder.set(sql);
	}
	
	private static class Work extends Thread{		
		private QuerySvc querySvc;		
		private String sql;		
		public Work(QuerySvc querySvc,String sql){
			this.querySvc = querySvc;
			this.sql = sql;
		}		
		 public void run() {
			 querySvc.setSql(sql);
			 querySvc.execute();
		 }
	}	
	public static void main(String args[]){		
		QuerySvc  querySrc = new QuerySvc();		
		for(int k=0;k<10;k++){
			String sql = "Select * from table where id =" + k;
			new Work(querySrc,sql).start();
		}		
	}		
}

 

   事例二:

 

/**
 * 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
 * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
 * 如果要保存多个线程变量,可定义多个ThreadLocal变量,
 * 或者将多个变量封装到一个对象中,将整个对象保存到ThreadLocal变量。
 *
 */
public class SequenceNumber {	
	private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){
		public Integer initialValue(){
			return 0;
		}
	};	
	public Integer getNextNum(){
		seqNum.set(seqNum.get()+1);
		return seqNum.get();
	}
	
	// 测试方法
	public static void main(String args[]){
		SequenceNumber sn = new SequenceNumber();
		// 3个线程共享sn,各自产生序列号 
		TestClient t1 = new TestClient(sn); 
		TestClient t2 = new TestClient(sn); 
		TestClient t3 = new TestClient(sn); 
		t1.start(); 
		t2.start(); 
		t3.start();
	}
	
	// 内部静态线程类
	private static class TestClient extends Thread{
		private SequenceNumber sn; 
		public TestClient(SequenceNumber sn) { 
			this. sn = sn; 
		} 
		public void run() 
		{ 
			//每个线程打出3个序列值 
			for (int i = 0; i < 3; i++) {
				System.out.println("thread["+Thread.currentThread().getName()+ 
				"] sn["+sn.getNextNum()+"]"); 
			}
		}
	}
}

 

 

分享到:
评论

相关推荐

    Java多线程编程实例

    本书“Java多线程编程实例”深入浅出地讲解了如何在Java环境中实现多线程操作,尽管出版时间较早,但其内容的经典性和实用性使其在现代开发中仍具有极高的参考价值。 首先,我们要理解Java中的线程是如何创建的。...

    java多线程进度条实例

    本实例将探讨如何利用Java实现一个具有进度条显示功能的多线程应用。进度条通常用于可视化地表示某个任务的完成程度,这对于长时间运行的操作如文件下载、上传或大型计算来说非常有用。 首先,我们要理解Java中的...

    JAVAJAVA多线程教学演示系统论文

    总的来说,《JAVA多线程教学演示系统》这篇论文不仅是对JAVA多线程技术的理论探讨,更是一个实践与教学相结合的优秀范例,对于提升学生的多线程编程能力具有很高的参考价值。VB图书管理系统论文范文虽不在本文讨论...

    java多线程示例

    在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。

    java多线程设计模式详解(PDF及源码)

    (注意,本资源附带书中源代码可供参考) 多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍Java线程相关的设计模式概念,并且通过实际的Java程序范例和 UML图示来一一解说,书中...

    java多线程学习

    在学习Java多线程的过程中,理解线程与进程的概念是非常基础且重要的一步。...在学习的过程中,还可以参考多种教学资源,比如课本、在线教程、开源项目代码等,不断地巩固和加深对Java多线程编程的理解。

    Java多线程矩阵相乘的代码

    这个压缩包中的内容,"Java多线程矩阵相乘的代码",显然提供了一个示例,演示如何利用多线程来加速矩阵乘法这一计算密集型操作。矩阵相乘在科学计算、图像处理、机器学习等领域广泛应用,其效率直接影响程序性能。 ...

    java多线程编程实战指南 核心篇 代码

    《Java多线程编程实战指南(核心篇)》以基本概念、原理与方法为主线,辅以丰富的实战案例和生活化实例,并从Java虚拟机、操作系统和硬件多个层次与角度出发,循序渐进、系统地介绍Java平台下的多线程编程核心技术及...

    java_Thread.rar_java 多线程_java多线程

    本资料"java_Thread.rar"提供了一些Java多线程的实践案例,对于深入理解和应用Java多线程技术具有很高的参考价值。 首先,我们要理解线程的基本概念。线程是程序执行的最小单元,每个线程都拥有自己独立的程序...

    duoxianchengxiazai.rar_Java 多线程 下载_java 多线程下载

    下面将详细讲解Java多线程下载的相关知识点: 1. **线程基础**:在Java中,线程是程序中的执行流。`Thread`类是所有线程的基类,我们可以通过继承它或实现`Runnable`接口来创建线程。创建线程主要有两种方式:直接...

    java线程简单实例.txt

    java Runnable线程简单实例。简单实用,可用可参考;多用多理解;线程可用用在很多场景,java程序猿必备技能

    java多线程设计模式

    Java多线程设计模式是Java开发中不可或缺的一部分,它涉及到如何在并发环境下高效、安全地组织程序执行。本文将深入探讨Java多...这份"java多线程设计模式"的PDF文档,无疑是一份宝贵的参考资料,值得深入学习和实践。

    java多线程学习java多线程学习.docx

    总的来说,Java多线程学习涵盖了线程的创建与管理、并发工具的使用、以及高级并发编程策略。理解并掌握这些知识,能够帮助开发者编写出高效、可靠的多线程应用。而Doug Lea的工作不仅推动了Java并发技术的发展,也为...

    java多线程总结

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。本文将深入探讨Java多线程的相关知识点,包括线程的创建、线程的状态、同步机制以及线程安全问题。 1. **线程的创建*...

    JAVA多线程设计模式

    本书《JAVA多线程设计模式》针对Java语言的多线程编程进行深入讲解,采用易于理解的方式介绍了与Java线程相关的多个设计模式,并通过实例程序与UML图示辅助阐述。书中的关键代码片段都有标注,易于读者理解与学习,...

    java多线程结合界面开发实例(原创)财务管理系统源代码和效果图[参考].pdf

    在这个实例中,我们将学习如何使用Java多线程技术结合界面开发来实现一个财务管理系统。这个系统能够实时显示财务状况,并且具有保存功能。 知识点1:Java多线程技术 在这个实例中,我们使用了Java多线程技术来...

    4JAVA编程高级-多线程编程

    ### JAVA编程高级-多线程编程 ...总之,Java中的多线程编程是一个非常重要的主题,对于提高程序的性能和响应速度有着不可替代的作用。掌握好Java中的多线程机制,可以帮助开发者更好地设计和实现高效的应用程序。

    图解java多线程设计模式-结城浩-完整高清带书签版本

    总之,《图解Java多线程设计模式》是一本深入浅出的多线程编程指南,它不仅涵盖了Java多线程的基础知识,还深入探讨了高级主题和最佳实践,对于想要提升并发编程能力的Java开发者来说,是一本不可多得的参考书。...

    7Java第七单元练习题-Java多线程机制[参考].pdf

    根据提供的文件信息,可以提炼出一系列关于Java多线程机制的知识点。以下知识点均围绕Java多线程展开,并详细解释涉及的概念和组件: 1. 多线程基础概念: - Java多线程是指在Java语言中能够同时执行多个线程的...

    多核多线程下java设计模式性能提升.pdf

    总结来说,本文档通过介绍单例模式在多核多线程环境下的性能提升方法,探讨了Java设计模式在现代大型系统应用中的优化策略,并对JDK未来的设计模式实现提出期望,为Java开发人员提供了宝贵的技术指导和参考。

Global site tag (gtag.js) - Google Analytics