Runnable接口
- Thread类实现了Runnable接口
- 只有一个run方法
- 更便于多线程共享资源
- Java不支持多继承,如果已经继承了某个基类,便需要实现Runnable接口来生成多线程
- 以实现runnable的对象为参数建立新的线程
- start方法启动线程就会运行run方法
以Runnable接口方法实现前面的求阶乘
class FactorialThread implements Runnable{
private int num;
public FactorialThread(int num) {
this.num = num;
}
public void run() {
int i = num;
int result = 1;
System.out.println("new thread start");
while(i>0) {
result = result * i;
i--;
System.out.println("The factorial of "+ num +" is "+ result);
System.out.println("new thread ends");
}
}
}
public class FactorialThreadTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("main thread starts");
FactorialThread t = new FactorialThread(10);
new Thread(t).start();
System.out.println("new thread started, main thread ends");
}
}
使用Runnable接口创建三个三线程,每个线程睡眠一段时间,然后结束
class TestThread implements Runnable{
private int sleepTime;
public TestThread() {
sleepTime = (int)(Math.random()*6000);
}
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" going to sleep for "+ sleepTime);
Thread.sleep(sleepTime);
}
catch(InterruptedException exception) {};
System.out.println(Thread.currentThread().getName()+" finished");
}
}
public class ThreadSleep {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestThread thread1 = new TestThread();
TestThread thread2 = new TestThread();
TestThread thread3 = new TestThread();
System.out.println("Stsrting threads");
new Thread(thread1,"Thread1").start();
new Thread(thread2,"Thread2").start();
new Thread(thread3,"Thread3").start();
System.out.println("Threads started,main ends\n");
}
}
线程间的数据共享
- 用同一个实现了Runnable接口的对象作为参数创建多个线程
- 多个线程共享同一对象中的相同数据
- 独立的同时运行的线程有时需要共享一些数据并且考虑到彼此的状态和动作
三线程数据共享:
class TestThread implements Runnable{
private int sleepTime;
public TestThread() {
sleepTime = (int)(Math.random()*6000);
}
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" going to sleep for "+ sleepTime);
Thread.sleep(sleepTime);
}
catch(InterruptedException exception) {};
System.out.println(Thread.currentThread().getName()+" finished");
}
}
public class ShareTargetTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*TestThread thread1 = new TestThread();
TestThread thread2 = new TestThread();
TestThread thread3 = new TestThread();
System.out.println("Stsrting threads");
new Thread(thread1,"Thread1").start();
new Thread(thread2,"Thread2").start();
new Thread(thread3,"Thread3").start();
System.out.println("Threads started,main ends\n");
*/
TestThread threadobj = new TestThread();
System.out.println("Starting threads");
new Thread(threadobj,"Thread1").start();
new Thread(threadobj,"Thread2").start();
new Thread(threadobj,"Thread3").start();
System.out.println("Thread started,main ends\n");
}
}
运行结果:
因为是用一个Runnable类型对象创建的3个线程,这三个线程就共享了这个对象的私有成员,在运行中,三个线程运行时间相同。
用三个线程模拟三个售票口,总共售出200张票
- 用三个线程模仿3个售票口的售票行为
- 这3个线程应该共享200张票的数据
class SellTickets implements Runnable{
private int tickets = 200;
public void run(){
while(tickets > 0) {
System.out.println(Thread.currentThread().getName()+" is selling tickets "+tickets--);
}
}
}
public class SellTicketsTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
SellTickets t = new SellTickets();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}
运行结果:
说明:
在这个例子中,创建了3个线程,每个线程调用的是同一个SellTickets对象中的run()方法,访问的是同一个对象中的变量(Tickets)