java 多线程 内部类实现

本文通过InnerThread1和InnerThread2展示了两种使用内部类创建线程的方式,一种是命名内部类,另一种是匿名内部类。同时,还介绍了使用Runnable接口实现线程的方式,以及在方法内部创建线程的方法,强调了线程安全和对象初始化的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



import java.util.concurrent.TimeUnit;

/**
 * InnerThread1 创建了一个扩展自Thread 的匿名内部类,
 * 并且在构造器中创建了一个内部类的一个实例。如果内部类
 * 具有你在其他方法中需要访问的特殊能力(新方法),那这么
 * 做将会很有意义。但是,在大多数时候,创建线程的原因只是为
 * 了使用Thread的能力,因此不必要创建匿名内部类。
 * 
 * @create @author Henry @date 2016-11-18
 */
// using a named inner class:
class InnerThread1 {
	private int countDown = 5;
	private Inner inner;

	private class Inner extends Thread {
		public Inner(String name) {
			super(name);
			start();
		}

		@Override
		public void run() {
			try {
				while (true) {
					System.out.println(this);
					if (--countDown == 0)
						return;
					sleep(10);
				}
			} catch (InterruptedException e) {
				System.out.println("interrupted");
			}
		}

		@Override
		public String toString() {
			return getName() + ": " + countDown;
		}
	}

	public InnerThread1(String name) {
		inner = new Inner(name);
	}
}

/**
 * InnerThread2展示了可替换的方式:在构造器中创建一个匿名的Thread子类,
 * 并且将其向上转型为Thread引用t.如果类中的其他方法需要访问t,那它们可以
 * 通过Thread接口来实现,并且不需要了解该对象的确切类型。
 * 
 * @create @author Henry @date 2016-11-18
 * 
 */
// Using an anonymous inner class:
class InnerThread2 {
	private int countDown = 5;
	private Thread t;

	public InnerThread2(String name) {
		t = new Thread(name) {
			@Override
			public void run() {
				try {
					while (true) {
						System.out.println(this);
						if (--countDown == 0)
							return;
						sleep(10);
					}
				} catch (InterruptedException e) {
					System.out.println("sleep() interrupted");
				}
			}

			public String toString() {
				return getName() + ":" + countDown;
			};
		};
		t.start();
	}
}

/**
 * 参考InnerThread1
 * 
 * @create @author Henry @date 2016-11-18
 * 
 */
// Using a named Runnable implememtation
class InnerRunnable1 {
	private int countDown = 5;
	private Inner inner;

	private class Inner implements Runnable {
		Thread t;

		public Inner(String name) {
			t = new Thread(this, name);
			t.start();
		}

		@Override
		public void run() {
			try {
				while (true) {
					System.out.println(this);
					if (--countDown == 0)
						return;
					TimeUnit.MILLISECONDS.sleep(10);
				}
			} catch (InterruptedException e) {
				System.out.println("sleep() interrupted");
			}
		}

		@Override
		public String toString() {
			return t.getName() + ":" + countDown;
		}
	}

	public InnerRunnable1(String name) {
		inner = new Inner(name);
	}
}

/**
 * 参考InnerThread2
 * 
 * @create @author Henry @date 2016-11-18
 * 
 */
// Using an anonymous Runnable implementation:
class InnerRunnable2 {
	private int countDown = 5;
	private Thread t;

	public InnerRunnable2(String name) {
		t = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					while (true) {
						System.out.println(this);
						if (--countDown == 0)
							return;
						TimeUnit.MILLISECONDS.sleep(10);
					}
				} catch (InterruptedException e) {
					System.out.println("sleep() interrupted");
				}
			}

			@Override
			public String toString() {
				return Thread.currentThread().getName() + ":" + countDown;
			}
		}, name);
		t.start();
	}
}

/**
 * ThreadMethod类展示了在方法内部如何创建线程。当你准备好运行线程时,
 * 就可以调用这个方法,而在线程开始之后,该方法将返回。如果该线程只执行辅助操作,
 * 而不是该类的重要操作,那么这与在该类的构造器内部启动线程相比,
 * 可能是一种更加有用而适合的方式。
 * 
 * @create @author Henry @date 2016-11-18
 * 
 */
// A separate method to run some code as a tack:
class ThreadMethod {
	private int countDown = 5;
	private Thread t;
	private String name;

	public ThreadMethod(String name) {
		this.name = name;
	}

	public void runTask() {
		if (t == null) {
			t = new Thread(name) {
				public void run() {
					try {
						while (true) {
							System.out.println(this);
							if (--countDown == 0)
								return;
							TimeUnit.MILLISECONDS.sleep(10);
						}
					} catch (InterruptedException e) {
						System.out.println("sleep() interrupted");
					}
				}

				public String toString() {
					return getName() + ":" + countDown;
				};
			};
			t.start();
		}
	}
}

/**
 * 在构造器中启动线程可能会变得很有问题,因为另一个任务可能会在构造器结束之前
 * 开始执行,这意味着该任务能够访问处于不稳定状态的对象。这是优先Executor而不
 * 是显式地创建Thread对象的另一个原因。
 * 有时通过使用内部类来将线程代码隐藏在类中将会很有用,就像如下这样:
 * 
 * @create @author Henry @date 2016-11-18
 */
public class ThreadVariations {

	public static void main(String[] args) {
		new InnerThread1("InnerThread1");
		new InnerThread2("InnerThread2");
		new InnerRunnable1("InnerRunnable1");
		new InnerRunnable2("InnerRunnable2");
		new ThreadMethod("ThreadMethod").runTask();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值