NumberThread 类是负责循环输出数字 1-26 的线程一
UpperCharThread 类是负责循环输出大写字母 A-Z 的线程二
LowerCharThread 类是负责循环输出小写字母 a-z 的线程三现在要实现的是一次输出 数字、大写字母、小写如:
1 A a
2 B b
. . .
. . .
26 Z z使用synchronized 和 wait() notify() 完成
UpperCharThread 类是负责循环输出大写字母 A-Z 的线程二
LowerCharThread 类是负责循环输出小写字母 a-z 的线程三现在要实现的是一次输出 数字、大写字母、小写如:
1 A a
2 B b
. . .
. . .
26 Z z使用synchronized 和 wait() notify() 完成
package hr.test;
//临界区,用于控制打印线程的工作顺序和互斥操作
class Mutex{
private int order=1; //记录线程顺序号
private int maxNum=0; //最大线程数
Mutex(int num){
this.maxNum=num;
}
//循环设置下一次要打印的顺序号
public void setOrder(){
this.order=(++order)<=maxNum?order:1;
}
//得到顺序号
public int getOrder(){
return this.order;
}
}
//打印工作
class PrintRunnable implements Runnable{
private Object[] cont=null; //打印内容
private int order=-1; //当前线程的打印顺序
private Mutex mutex=null; //临界区对象
PrintRunnable(Object[] c,int o,Mutex m){
this.cont=c;
this.order=o;
this.mutex=m;
}
public void run(){
try{
//循环打印内容
for(Object c:cont){
//互斥操作临界区
synchronized(mutex){
//如果当前工作线程的顺序号不等于临界区的顺序号,则工作线程等待阻塞,并放弃锁
while(mutex.getOrder()!=this.order)
mutex.wait();
//打印内容
System.out.println(c);
//设置下一次允许打印的线程顺序
mutex.setOrder();
//唤醒在临界区等待的所有线程
mutex.notifyAll();
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}//测试
public class Test { public static void main(String[] args){
Integer[] number={1,2,3,4};
Character[] upperChar={'A','B','C','D'};
Character[] lowerChar={'a','b','c','d'};
Mutex mutex=new Mutex(3);
new Thread(new PrintRunnable(number,1,mutex)).start();
new Thread(new PrintRunnable(upperChar,2,mutex)).start();
new Thread(new PrintRunnable(lowerChar,3,mutex)).start();
}
}
谢谢解答!
我还想再问下,如果用以下的代码作为基础该怎么实现,这个是作业...
package com.test;class NumberThread extends Thread { public void run() {
for (int i = 1; i <= 26; i++) {
System.out.println(i);
}
}
}class BigCharThread extends Thread {
public void run() {
for (int i = 'A'; i <= 'Z'; i++) {
System.out.println((char) i);
}
}
}class SmallCharThread extends Thread {
public void run() {
for (int i = 'a'; i <= 'z'; i++) {
System.out.println((char) i);
}
}
}public class ThreeThread {
public static void main(String[] args) {
NumberThread num = new NumberThread();
BigCharThread big = new BigCharThread();
SmallCharThread small = new SmallCharThread();
num.start();
big.start();
small.start();
}
}
class Mutex{
private int order=1; //记录线程顺序号
private int maxNum=0; //最大线程数
Mutex(int num){
this.maxNum=num;
}
//循环设置下一次要打印的顺序号
public void setOrder(){
this.order=(++order)<=maxNum?order:1;
}
//得到顺序号
public int getOrder(){
return this.order;
}
}
//打印工作
class PrintRunnable implements Runnable{
private Object[] cont=null; //打印内容
private int order=-1; //当前线程的打印顺序
private Mutex mutex=null; //临界区对象
PrintRunnable(Object[] c,int o,Mutex m){
this.cont=c;
this.order=o;
this.mutex=m;
}
public void run(){
try{
//循环打印内容
for(Object c:cont){
//互斥操作临界区
synchronized(mutex){
//如果当前工作线程的顺序号不等于临界区的顺序号,则工作线程等待阻塞,并放弃锁
while(mutex.getOrder()!=this.order)
mutex.wait();
//打印内容
System.out.print(c+" ");
if(mutex.getOrder()==3)
System.out.println();
//设置下一次允许打印的线程顺序
mutex.setOrder();
//唤醒在临界区等待的所有线程
mutex.notifyAll();
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}//测试
public class ThreeThread { public static void main(String[] args){
Integer[] number={1,2,3,4};
Character[] upperChar={'A','B','C','D'};
Character[] lowerChar={'a','b','c','d'};
Mutex mutex=new Mutex(3);
new Thread(new PrintRunnable(number,1,mutex)).start();
new Thread(new PrintRunnable(upperChar,2,mutex)).start();
new Thread(new PrintRunnable(lowerChar,3,mutex)).start();
}
}输出结果:
1 A a
2 B b
3 C c
4 D d
我线程方面也不太会,但是给写了一个程序,供大家讨论:package thread;class NumberThread extends Thread {
int index = 0;
Munex mu = new Munex(); public NumberThread(Munex mu) {
this.mu = mu;
} public void run() {
for (int i = 1; i <= 26; i++) {
mu.shuChu(index);
System.out.print(i + " ");
}
} public int getIndex() {
return index;
}
}class BigCharThread extends Thread {
int index = 1;
Munex mu = new Munex(); public BigCharThread(Munex mu) {
this.mu = mu;
} public void run() {
for (int i = 'A'; i <= 'Z'; i++) {
mu.shuChu(index);
System.out.print((char) i + " ");
}
} public int getIndex() {
return index;
}
}class SmallCharThread extends Thread {
int index = 2;
Munex mu = new Munex(); public SmallCharThread(Munex mu) {
this.mu = mu;
} public void run() {
for (int i = 'a'; i <= 'z'; i++) {
mu.shuChu(index);
System.out.println((char) i + " ");
}
}
}class Munex {
int index = 0; synchronized public void shuChu(int index) {
while (this.index != index) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// System.out.println(index+"@@@");
setIndex();
//问题是为什么在这里休眠一会结果就没有问题,不休眠就会有问题呢?
//希望高手能给予指点一下。
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.notifyAll();
} public void setIndex() {
if (index == 2)
index = 0;
else
index++;
}
}public class ThreeThread {
public static void main(String[] args) {
Munex mu = new Munex();
NumberThread num = new NumberThread(mu);
BigCharThread big = new BigCharThread(mu);
SmallCharThread small = new SmallCharThread(mu);
num.start();
big.start();
small.start();
}
}
输出结果:
1 A a
2 B b
3 C c
4 D d
5 E e
6 F f
7 G g
8 H h
9 I i
10 J j
11 K k
12 L l
13 M m
14 N n
15 O o
16 P p
17 Q q
18 R r
19 S s
20 T t
21 U u
22 V v
23 W w
24 X x
25 Y y
26 Z z
在这里我有个问题就是:
为什么在Munex类里休眠一会结果就没有问题,不休眠就会有问题呢?
希望高手能给予指点一下。
package com.test;class NumberThread extends Thread { public void run() {
for (int i = 1; i <= 26; i++) {
System.out.println(i);
}
}
}class BigCharThread extends Thread {
public void run() {
for (int i = 'A'; i <= 'Z'; i++) {
System.out.println((char) i);
}
}
}class SmallCharThread extends Thread {
public void run() {
for (int i = 'a'; i <= 'z'; i++) {
System.out.println((char) i);
}
}
}public class ThreeThread {
public static void main(String[] args) {
NumberThread num = new NumberThread();
BigCharThread big = new BigCharThread();
SmallCharThread small = new SmallCharThread();
num.start();
big.start();
small.start();
}
}使用join()方法,在大写字母里 写数字线程.join() 在小写字母里 写 大写字母.join()
实现代码如下:
package com.test;class NumThread1 extends Thread {
public void run() {
for(int i=1;i<=26;i++){
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}class BigCharThread extends Thread{
private Thread person;
public BigCharThread(Thread person) {
this.person=person;
}
public void run() {
try {
person.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i='A';i<='Z';i++){
System.out.println((char)i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}class SmallCharThread extends Thread{
private Thread person;
public SmallCharThread(Thread person) {
this.person=person;
}
public void run() {
try {
person.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i='a';i<='z';i++){
System.out.println((char)i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class NumChar {
public static void main(String[] args) {
NumThread1 n=new NumThread1();
BigCharThread b=new BigCharThread(n);
SmallCharThread s=new SmallCharThread(b);
n.start();
s.start();
b.start();
}}
下面的代码使用了一个令牌传递的机制,每个拥有控制权的线程在做完自己的事情后把控制权交给下一个线程,而不是唤醒所有线程class ThreadNode
{
boolean hasToken = false;//true if this is first Thread
Node next;//need initialized
synchronized void waitToken() throws InterruptedException
{
while(!hasToken)
this.wait();
}
void switchNext()
{
this.hasToken = false;
next.setToken();
}
synchronized void setToken()
{
this.hasToken = true;
this.notifyAll();
}
public void loop() throws InterruptedException
{
for(;;)
{
this.waitToken();
//do my jobs
this.switchNext();
}
}
}