`

java Thread线程实例

 
阅读更多
synchronized使用起来非常简单,有三种使用模式:

1. 作为修饰符加在方法声明上,synchronized修饰非静态方法时表示锁住了调用该方法的堆对象,修饰静态方法时表示锁住了这个类在方法区中的类对象(记住JAVA中everything is object)。

2.可以用synchronized直接构建代码块。

3.在使用Object.wait()使当前线程进入该Object的阻塞队列时,以及用Object.notify()或Object.notifyAll()唤醒该Object的阻塞队列中一个或所有线程时,必须在外层使用synchronized (Object),这是JAVA中线程同步的最常见做法。之所以在这里要强制使用synchronized代码块,是因为在JAVA语义中,wait有出让Object锁的语义,要想出让锁,前提是要先获得锁,所以要先用synchronized获得锁之后才能调用wait,notify原因类似,另外,我们知道操作系统信号量的增减都是原子性的,而Object.wait()和notify()不具有原子性语义,所以必须用synchronized保证线程安全。

另外,在使用synchronized时有三个原则:

a) sychronized的对象最好选择引用不会变化的对象(例如被标记为final,或初始化后永远不会变),原因显而易见的,虽然synchronized是在对象上加锁,但是它首先要通过引用来定位对象,如果引用会变化,可能带来意想不到的后果,对于需要synchronized不同对象的情况,建议的做法是为每个对象构建一个Object锁来synchronized(不建议对同一个引用反复赋值)。当然将synchronized作为修饰符修饰方法就不会有引用变化的问题,但是这种做法在方法体较大时容易违反第二个原则。

b) 尽可能把synchronized范围缩小,线程互斥是以牺牲并发度为代价的,这点大家都懂。

c) 尽量不要在可变引用上wait()和notify()。


现在需要计算1+2+3+....+30000的和。请采用多线程完成此计算工作,要求如下:
主线程启动三个线程,分别给它们分派以下任务:

线程1:计算1+2+3+...+10000

线程2:计算10001+10002+...+20000

线程3:计算20001+20002+...+30000

等三个线程都完成工作之后,主线程汇总三个工作线程的计算结果,得到最终答案:

1 + 2 + 3 + .... + 30000 = 450015000

/**
 * 
 */
package test.SyncAdd;

/**       
 * @projectName:zhngdps 
 * @packageName: test.SyncAdd
 * @ClassName  : SyncAddTest
 * @createBy   :Test 
 * @createDate :2014-6-5 上午09:03:35   
 * @useFor     : 
 *    
 */
public class SyncAddTest {

	private int getAddCount(int begin,int end,String threadName)
	{
		 TestA test1 = new TestA(begin,end);
	     Thread th1 = new Thread(test1,threadName);
	     th1.start() ;
	     /*
	      * 对线程对象加锁  针对的是同一个类的多个对象的线程
	      * 使得多线程运行结果可以控制,synchronized用于保护共享数据
	      */
	     synchronized (th1) {
		    	try {
		    	   th1.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		  return test1.getSum() ;
		}
    }
	
	public static void main(String[] args) {
		SyncAddTest t = new SyncAddTest();
		int sum1 = t.getAddCount(0,10000,"th1");
		System.out.println(sum1);
		int sum2 = t.getAddCount(10001,20000,"th2") ;
		System.out.println(sum2);
		int sum3 = t.getAddCount(20001,30000,"th3") ;
		System.out.println(sum3);
		int sum = sum1 + sum2 + sum3 ;
		System.out.println(sum);

	}
};

class TestA implements Runnable
{
	private int begin ;
	private int end ;
	private int sum = 0;
	public TestA(int begin,int end)
	{
		this.begin = begin ;
		this.end = end ;
	}
	@Override
	public void run() {
		add();
		System.out.println(Thread.currentThread().getName());
	}
	
	private void add()      
	{
		for(int i=begin;i<=end;i++)
		{
			sum += i ;
		}
	}
	
	public int getSum()
	{
		return this.sum ;
	}
};


使用while true的方式进行阻塞主函数从而使线程继续执行直到线程执行完毕


class ThTest implements Runnable {

	private int start;

	private int end;

	private int sum = 0;

	private boolean isComplete = false;

	public boolean isComplete() {
		return isComplete;
	}

	public ThTest() {
		super();
	}

	public ThTest(int start, int end) {
		this.start = start;
		this.end = end;
	}

	public int getSum() {
		return this.sum;
	}

	@Override
	public void run() {
		synchronized (this) {
			for (int i = start; i <= end; i++) {
				sum += i;
			}
			isComplete = true;
		}
	}
public static void main(String[] args) {
		
		ThTest thTest01 = new ThTest(1, 50000);
		ThTest thTest02 = new ThTest(50001, 100000);

		Thread thread01 = new Thread(thTest01);
		Thread thread02 = new Thread(thTest02);
		
		ExecutorService threaPool = Executors.newCachedThreadPool();
		threaPool.execute(thread01);
		threaPool.execute(thread02);

		while (true) {
			System.out.print("");
			if (thTest01.isComplete() && thTest02.isComplete()) {
				break;
			}
		}

		System.out.println("总数为:" + (thTest01.getSum() + thTest02.getSum()));
		threaPool.shutdown();
	}
};
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    java 多线程并发实例

    本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是程序执行的基本单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈,而共享堆...

    JAVA多线程的实例

    在Java中,实现多线程有两种主要方式:通过实现`Runnable`接口或者继承`Thread`类。 首先,让我们从创建线程开始。当你有一个实现了`Runnable`接口的类时,你可以创建一个`Thread`对象并传入你的`Runnable`实例,如...

    java多线程的讲解和实战

    4. **线程优先级与调度**:Java的`Thread`类提供了设置线程优先级的方法,如`setPriority(int priority)`,但实际线程调度依赖于操作系统的策略,优先级并不保证绝对的执行顺序。 5. **守护线程(Daemon)**:守护...

    java线程实例 各种小Demo

    Java线程是多任务编程的重要概念,它允许程序同时执行多个独立的任务,从而...在"线程池.rar"和"线程实例"这两个文件中,你可以找到关于这些概念的具体示例代码,通过学习和实践,可以深入理解Java线程的运用和管理。

    Java多线程实例图形版

    总结起来,"Java多线程实例图形版"是一个结合理论与实践的教学资源,通过“哲学家就餐问题”这一经典案例,帮助开发者理解多线程的基本概念、并发问题以及解决策略。通过学习这个实例,不仅可以掌握Java多线程编程的...

    Java多线程实例代码

    在Java中,实现多线程有两种主要方式:通过继承`Thread`类和实现`Runnable`接口。 1. 继承Thread类: 当你需要创建一个新的线程时,可以创建一个新类来继承`Thread`类。重写`run()`方法,在其中编写线程要执行的...

    java多线程编程实例_Source

    在本实例源码中,包含17个章节和上百个实例,旨在深入讲解Java多线程的核心概念和实际应用。 一、线程基础知识 在Java中,线程是程序的执行流,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存...

    java多线程实例

    Java 多线程实例 Java 多线程是Java编程语言的一个重要特性,它使得程序能够在同一时间执行多个任务,从而提高系统效率和资源利用率。本文将深入探讨Java中的线程概念、创建线程的方式以及如何实现线程的并发执行。...

    java多线程实例 代码可执行 绝对开源

    总的来说,这个"java多线程实例"是一个实用的学习资源,它展示了如何利用Java的多线程特性进行高效的网络下载,并通过合理的线程同步和文件操作来实现资源的合并。对于想要深入理解Java多线程和网络编程的开发者来说...

    Java多线程编程实例

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

    java 多线程实例

    Java多线程是Java编程中的重要概念,尤其在并发编程领域有着广泛的...通过对"java多线程实例"的学习,开发者可以深入理解线程的工作原理,提升解决并发问题的能力,这对于开发高并发的网络服务、数据库应用等至关重要。

    java多线程编程实例

    ### Java多线程编程实例解析 #### 1. 创建线程的方式 在Java中,创建线程有两种主要方式:通过继承`Thread`类或实现`Runnable`接口。 - **继承Thread类**:创建一个新类继承自`Thread`,并重写其`run()`方法。在`...

    eclipse项目java线程实例

    在这个"Eclipse项目java线程实例"中,我们可以深入理解并实践Java线程的创建、管理和同步机制。 首先,Java线程允许程序同时执行多个不同的任务,从而提高系统的效率和响应性。Java提供了两种创建线程的方式:通过...

    Java线程实例

    Java线程实例通常包括生产者消费者模型、哲学家就餐问题、银行家算法等经典案例,这些实例有助于理解线程的同步、协作和资源管理。 总结来说,Java线程是Java编程中不可或缺的一部分,理解和掌握线程的创建、同步、...

    《Java多线程编程实例》随书源码

    《Java多线程编程实例》这本书深入浅出地探讨了Java中的多线程编程,通过丰富的实例帮助读者理解和掌握这一复杂主题。随书源码提供了实际操作的机会,以便读者能够亲手实践书中的示例,加深理解。 1. **线程创建...

    java多线程实例 源码

    在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类 当创建一个新的线程时,可以通过创建Thread类的新实例并重写其run()方法来实现。run()方法包含线程要执行的代码。一旦调用...

    java多线程thread实例

    `Thread`类是Java中的核心类,它允许我们创建并控制独立的执行线程。在这个实例中,我们将深入探讨如何使用`Thread`类创建和管理多线程。 1. **线程的基本概念** - **线程**:线程是程序执行的最小单元,一个进程...

    java多线程编程实例 (源程序)

    在Java中,多线程可以通过实现Runnable接口或继承Thread类来创建。下面我们将深入探讨Java多线程编程的相关知识点。 1. **线程的创建** - 实现Runnable接口:这是推荐的方式,因为Java类只能单继承,通过实现...

Global site tag (gtag.js) - Google Analytics