`
ftj20003
  • 浏览: 132047 次
  • 性别: Icon_minigender_1
  • 来自: ...
社区版块
存档分类
最新评论

一道多线程趣味热身题

    博客分类:
  • Java
阅读更多
    保持对知识点或者技术的熟悉度对于程序员至关重要,要学会一个技术点可能不需要很多精力或者时间,但是要精通或者长时间保持对其的熟悉程度往往非常困难。个人的观点是通过演练对自己掌握的知识点保鲜是一个很好的途径。这其中包括了写Blog阐述,对周围的爱好者演讲,与其他程序员交流辩论以及最重要的多找机会去写相关的程序或者解决相关的问题,难点来加深理解和延长熟悉度。所以我通过写Blog和找相关的问题解决来试图延长对某个知识点的熟知度,毕竟长时间不用,不理会的东西不管什么都会自然的被遗忘。多线程相关的编程对于Web应用开发过程中使用的机会很少,所以只有自己找一些题目或者问题演练。

    之前看到过这样的一个题目:三个线程,线程名分别为A、B、C,设计程序使得三个线程循环打印“ABC”10次后终止。这个题目相对于我之前写的那个疑似Google面试题来说要简单的多。可以看成是三个线程写一个文件的简化版本,不需要考虑调整优先级。主要思路一致:记录最后一次写入的位置。具体的代码示例如下:
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: yanxuxin
 * @date: 2010-2-25
 */
public class WarmUpForThread {

	/** 线程名数组*/
	private final String[] names = {"A","B","C"};
	
	/** 循环执行的总长度*/
	private final int size = names.length * 10;
	
	private final ReentrantLock lock = new ReentrantLock();
	
	/** 记录最后一次写入的元素在数组的位置*/
	private int latestPos = 0;
	
	/** 记录总体打印次数*/
	private volatile int counter = 1;
	
	public static void main(String[] args) {
		WarmUpForThread demo = new WarmUpForThread();
		demo.startDemo();
	}
	
	/**
	 * 开启3个线程,线程名对于数组常量
	 */
	public void startDemo() {
		for(String name : names) {
			new PrintWorker(name).start();
		}
	}
	
	/**
	 * 多线程竞争执行具体打印任务的方法
	 * @throws InterruptedException
	 */
	public void print() throws InterruptedException {
		String name = Thread.currentThread().getName();
		
		lock.lockInterruptibly(); // 可以响应线程中断信号
		try{
			if(names[latestPos].equals(name) && counter <= size) {
				latestPos = (latestPos + 1) % names.length;
				counter++;
				System.out.print(name);
			}
		}
		finally{
			lock.unlock();
		}
		
		Thread.sleep(50);
	}
	
	/**
	 * 执行打印任务的线程
	 * @author: yanxuxin
	 * @date: 2010-2-25
	 */
	class PrintWorker extends Thread {
		
		public PrintWorker(String name) {
			super(name);
		}
		
		public void run() {
			while(counter <= size) {
				try {
					print();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

    这里用于记录以操作总数的counter利用了volatile的可见性的特性。多个子线程可以同时得到最新的counter的值,又由于对counter的递增与改变latestPos值的操作是一个共同的原子操作,所以可以使用lock来确保counter++的线程安全。故基于上述的原因使用volatile关键字。另外一点是在print方法里也使用counter <= size检查条件的原因是:当counter=29,一个线程执行counter++之前,其余的线程中的一个或者多个counter <= size条件依然满足,故都进入竞争等待阶段,所以一旦进入lock块就意味着counter实际已经30了,不应该再继续打印,故print()方法内依然有此条件检查。

    这个例子虽然相对简单,但是也是一样考察了线程调度的问题。暂时没有无锁实现的清晰的思路,所以只是使用另一种线程同步的机制ReentrantLock演练一下。最近开始找工作,不知笔试或者面试中能不能激发多一点的多线程方面的灵感和领悟,呵呵。找工作虽然比较难,但是希望自己能在这个陌生的城市坚持并如愿...
4
0
分享到:
评论
发表评论

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

相关推荐

    CC++多线程编程练习题大全

    **CC++多线程编程**是现代软件开发中的重要组成部分,尤其在高性能计算、服务器端应用和实时系统中,多线程技术能充分利用多核处理器的资源,提高程序的执行效率。以下是一些关于CC++多线程编程的核心知识点: 1. *...

    多线程面试题

    本文将围绕“多线程面试题”这一主题,深入探讨相关概念、技术及其应用。 1. **线程的概念**:线程是程序执行的最小单位,一个进程可以有多个线程同时执行任务,提高了程序的运行效率。 2. **Java中的线程创建方式...

    C#面试题 包括 ADO.net 多线程等

    C#面试题 包括 ADO.net 多线程等 C#面试题 包括 ADO.net 多线程等 C#面试题 包括 ADO.net 多线程等 C#面试题 包括 ADO.net 多线程等 C#面试题 包括 ADO.net 多线程等

    java基础多线程练习题(1)

    总结来说,Java基础多线程练习题主要涵盖了线程的创建、同步与通信、线程安全以及并发工具的使用。通过这些题目,你可以更好地理解线程的工作原理,学会在实际项目中有效利用多线程提高程序性能,避免潜在的问题。在...

    多线程面试59题(含答案).pdf

    多线程面试59题(含答案)是关于多线程编程的知识点总结,涵盖了多线程的基本概念、优点、线程和进程的区别、Java 实现多线程的方式、启动线程方法的区别、终止线程的方式、线程的生命周期、wait()和 sleep()方法的...

    java面试题_多线程(68题).pdf

    Java中的多线程是面试中常见的话题,涵盖了操作系统的基础概念以及Java并发库的高级特性。以下是对这些知识点的详细解释: 1. **线程**:线程是操作系统调度的基本单元,一个进程中可以有多个线程并发执行。在多...

    多线程经典面试题和答案

    ### 多线程经典面试题解析 #### Java 实现线程的方式 1. **继承 `Thread` 类**:这是最直接的方式,通过继承 `Thread` 类,并重写 `run()` 方法来实现线程的逻辑。这种方式简单直接,但是因为 Java 不支持多重继承...

    java多线程面试题和答案

    以下是一些关于Java多线程的面试题及其答案,涵盖了基础概念、并发控制、线程安全以及性能优化等方面。 1. **什么是Java多线程?** 多线程是指在单个程序中同时执行多个线程,这样可以提高应用程序的效率和响应...

    史上最全 Java 多线程面试题及答案

    Java多线程是Java编程中不可或缺的一部分,它允许并发执行多个任务,从而提高应用程序的效率和响应速度。本文将深入探讨Java多线程的相关知识点,包括它的用途、创建线程的方式、start()与run()的区别、Runnable和...

    java多线程面试题59题集合

    以下是对Java多线程面试题59题集合中可能涉及的一些关键知识点的详细解析。 1. **线程的创建方式** - 继承Thread类:创建一个新的类,该类继承自Thread类,并重写其run()方法。 - 实现Runnable接口:创建一个实现...

    多线程练习题java

    java多线程初学者练习题目,供初学者练习使用

    java多线程知识讲解及练习题

    Java 多线程知识讲解及练习题 Java 多线程基础知识的了解是 Java 程序设计的重要组成部分,本资源摘要信息对 Java 多线程基础知识进行了详细的讲解和练习题。 1. sleep() 和 wait() 的区别 sleep() 是 Thread 类...

    C#多线程互斥实例 多线程获取同一变量

    在编程领域,多线程是实现并发执行任务的重要机制,特别是在现代计算机系统中,多核处理器使得多线程成为提高程序性能的关键手段。C#语言提供了丰富的多线程支持,让我们能够编写出高效的多线程应用程序。在这个"多...

    2020面试题总结多线程篇.pdf

    面试题总结——多线程篇 一、多线程实现方式 多线程实现方式主要有四种:继承 Thread 类、实现 Runable 接口、实现 Callable 接口、通过 FutureTask 包装器。这四种方式可以满足不同的需求,例如继承 Thread 类...

    多线程,多线程面试题,C#

    在IT领域,多线程是程序设计中的一个重要概念,尤其在C#这样的.NET框架下,多线程的应用广泛且深入。本文将详细讲解C#中多线程的基础知识,以及在面试...同时,熟悉多线程面试题有助于在求职过程中展示自己的专业能力。

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例),可直接运行

    在.NET框架中,C#语言提供了强大的多线程支持,使得开发者可以充分利用现代多核处理器的优势,实现并行处理和高效能编程。本资源包含六个C#.NET多线程的实例,涵盖了多线程的基本使用到更高级的概念,如线程互斥。...

    c++笔试面试之网络和多线程

    在C++笔试面试中,网络和多线程是两个经常被提及的重要知识点。本篇文档详细列举了关于网络部分的面试题目,同时也涉及了与多线程相关的TCP/IP协议栈的建立和断开过程。以下为详细的知识点总结: 1. TCP服务创建...

    C#多线程读写sqlite

    在C#编程中,多线程技术常用于提高应用程序的执行效率,特别是在处理数据库操作时。SQLite是一款轻量级、嵌入式的关系型数据库,它广泛应用于桌面应用、移动设备和Web开发。当多线程环境对SQLite进行读写操作时,...

Global site tag (gtag.js) - Google Analytics