`

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC

 
阅读更多

 

package test1;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * 编写一个程序,开启3个线程,
 * 这3个线程的ID分别为A、B、C,
 * 每个线程将自己的ID在屏幕上打印10遍,
 * 要求输出结果必须按ABC的顺序显示;
 * 如:ABCABC….依次递推
 * 
 * 设计:LOCK+condition(可以把A、B、C理解成主线程,子线程,孙线程)
 * @author Mahone
 *
 */
public class Test3 {
	public static void main(String[] args) {
		Test3 obj = new Test3();
		obj.init();
	}
	
	private void init() {
		final Test3Business tb = new Test3Business();
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					tb.printA();
				}
			}
		});
		t1.setName("A");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					tb.printB();
				}
			}
		});
		t2.setName("B");
		
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					tb.printC();
				}
			}
		});
		t3.setName("C");
		
		t1.start();
		t2.start();
		t3.start();
	}
}

class Test3Business {
	
	private String flag = "A";
	
	private Lock lock = new ReentrantLock();
	
	private Condition cA = lock.newCondition();
	private Condition cB = lock.newCondition();
	private Condition cC = lock.newCondition();
	
	public void printA () {
		try {
			lock.lock();
			if (!flag.equals("A")) {
				cA.await();
			}
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			flag = "B";
			cB.signal();
		} catch (Exception ex) {
			ex.printStackTrace();
		}finally {
			lock.unlock();
		}
	}
	
	public void printB () {
		try {
			lock.lock();
			if (!flag.equals("B")) {
				cB.await();
			}
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			flag = "C";
			cC.signal();
		} catch (Exception ex) {
			ex.printStackTrace();
		}finally {
			lock.unlock();
		}
	}
	
	public void printC () {
		try {
			lock.lock();
			if (!flag.equals("C")) {
				cC.await();
			}
			System.out.println(Thread.currentThread().getName());
			Thread.sleep(1000);
			flag = "A";
			cA.signal();
		} catch (Exception ex) {
			ex.printStackTrace();
		}finally {
			lock.unlock();
		}
	}
}

 

 

分享到:
评论

相关推荐

    3个线程,根据不同规则打印线程名称

    在这个例子中,我们可以选择任意一种方式,为每个线程定义一个打印线程名称的方法。 ```java class PrintTask implements Runnable { private String name; public PrintTask(String name) { this.name = name...

    易语言多线程多次启动一个子程序

    每个线程都有自己的执行路径,它们共享进程的内存空间,但各自拥有独立的执行栈。在易语言中,通过创建和管理线程,可以实现并发执行任务,提高程序的运行效率。 三、易语言中的多线程实现 在易语言中,我们可以...

    实现一个数据单元,包括学号和姓名两部分。编写两个线程,一个线程往数据单元中写,另一个线程往出读。要求每写一次就往出读一次。

    本实验的任务是设计并实现一个数据单元,该单元包含学号和姓名两个字段,并且使用两个线程,一个用于写入数据,另一个用于读取数据。这种设计模式被称为“生产者-消费者”问题,是多线程编程中的经典案例。 首先,...

    理解多线程,写一个多线程应用程序,要求能在用户级实现线程的调度,如启动、挂起、恢复、停止,的C thread、java thread实现。

    线程是操作系统分配CPU时间的基本单位,每个线程都有自己的程序计数器、栈、局部变量等,但共享同一块内存空间,包括全局变量和静态变量。线程间的通信比进程间通信更为高效,因为它们共享相同的地址空间。 在C语言...

    c语言多进程多线程编程

    1. **进程定义**:进程是程序的一次执行实例,每个进程都有自己的独立内存空间,包括代码、数据和栈。在操作系统中,进程是资源分配的基本单位。 2. **创建进程**:在C语言中,可以使用`fork()`函数创建新进程。`...

    C++多线程 最简易的多线程程序

    这样,每个线程都有自己的变量副本。 在标签“建议模拟多线程”中,可能是指通过模拟并发情况来学习多线程。这可以通过编写多个简单的线程函数,观察它们如何相互交互和竞争资源来实现。 在实际开发中,多线程应用...

    win32多线程例子(c语言)

    `win32多线程例子(c语言)`这个项目就是一个很好的起点,它旨在帮助初学者理解如何在Win32 API环境下编写多线程程序。下面我们将深入探讨多线程的概念、Win32 API在创建线程中的作用以及如何使用C语言来实现这一...

    linux下C语言多线程编程实例

    8. **内存初始化**:`memset(&thread, 0, sizeof(thread))`用于将线程数组`thread`清零,这是为了确保在使用`pthread_create()`之前线程ID的初始值为0。 9. **错误检查**:在创建线程时,`pthread_create()`函数...

    linux 进程线程小程序

    每个进程都有一个唯一的进程ID(PID),并且可以拥有多个子进程。通过`ps`命令可以查看当前系统中的进程状态。 线程则是进程内部的一个执行单元,共享同一块内存空间,因此线程间的通信更为高效。线程间可以快速地...

    采用_beginthreadex创建多线程

    `_beginthreadex`函数接受几个参数,包括一个安全属性指针、初始堆栈大小、一个线程函数指针、传递给线程函数的参数、线程的创建标志以及一个线程ID的输出指针。线程函数是新线程将执行的代码入口点。下面是一个简单...

    c++多线程实例程序

    - **函数原型**: 每个线程都从一个特定的函数开始执行,这个函数必须具有如下原型: ``` DWORD WINAPI YourThreadFunc(LPVOID lpvThreadParm); ``` 其中`lpvThreadParm`是一个`LPVOID`类型的参数,可以是一个`...

    c语言多进程多线程编程.pdf

    1. **进程表分配**: 内核为新进程在进程表中分配一个表项。 2. **进程标识号分配**: 分配一个唯一的进程标识号(PID),用于唯一标识这个进程。 3. **资源复制**: 子进程会复制父进程的数据段、堆栈段和代码段等资源...

    用c#编写的启动线程程序

    线程是在一个进程中并行执行的子任务,每个线程都有自己的执行序列,可以独立地执行代码。在多核或多处理器系统中,线程能充分利用硬件资源,提高程序的运行效率。在用户界面应用中,使用线程可以避免UI线程(主线程...

    一个创建多线程的例子

    线程是程序执行的最小单元,每个线程都有自己的执行路径,可以独立地执行代码。在一个进程中,可以有多个线程共享同一块内存空间,包括全局变量、静态变量等,这使得线程间的数据交换变得简单且高效。 在Windows...

    易语言线程中的变量应用

    3. **线程局部存储**:易语言可能提供了线程局部存储(TLS)机制,允许为每个线程分配独立的数据存储区域。这样,每个线程都可以有自己的版本同一变量,而不会互相干扰。 4. **线程标识符**:`GetCurrentThreadId`...

    POSIX多线程程序设计中文版-Examples

    7. **线程局部存储**:`pthread_key_create()`和`pthread_getspecific()`、`pthread_setspecific()`函数可用于创建线程局部存储,这是一种在线程间隔离数据的方法,每个线程都有自己的副本。 8. **线程安全**:在多...

    多线程程序小例子实现

    每个线程都有自己的程序计数器、栈和局部变量,但共享同一块内存空间,包括全局变量和静态变量。这种特性使得多线程程序可以在处理I/O操作或等待资源时,其他线程仍能继续执行,提高了程序响应速度。 二、启动线程 ...

    Nachos的线程管理模块升级

    在实现中,可以通过在`Thread`类中增加整型变量`tid`来存储线程ID,并使用全局变量`id_port`来进行ID的分配和管理,确保每个新创建的线程都有一个唯一的ID。 二、扩展线程状态 线程状态的扩展增加了"挂起"这一状态...

    Posix多线程编程[总结].pdf

    每个线程也有一个线程ID,进程ID在整个系统中是唯一的,但线程不同,线程ID只在它所属的进程环境中有效。线程ID用pthread_t数据类型来表示,实现的时候可以用一个结构来代表pthread_t数据类型,因此不能把它作为整数...

Global site tag (gtag.js) - Google Analytics