- 线程 是程序中的执行线程。多线程的实现方式有两种,一种是继承Thread类,另一种是实现runnable接口。
- 先说继承Thread类,实现方式是:将类声明为
Thread
的子类。该子类应重写Thread
类的run
方法。接下来可以分配并启动该子类的实例。 - 就以多个窗口售票为例:
结果是多个窗口一同卖这100张票,其中多个线程将使用tick,必须将其静态使得数据量一定。package com.zk.thread; //接口继承实现多个串口的售票功能 class Tick extends Thread{ static int tick = 100;//一共100张票 public Tick(String name){ super(name); } public void run(){ while(true){ if(tick>0)//保证票数大于0 System.out.println(currentThread().getName()+" sell the "+tick--+" ticket"); } } } public class TicketDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Tick t1 = new Tick("窗口1"); Tick t2 = new Tick("窗口2"); Tick t3 = new Tick("窗口3"); Tick t4 = new Tick("窗口4"); t1.start(); t2.start(); t3.start(); t4.start(); } }
但是当类需要继承其他类怎么办呢,java中只支持单继承,这就需要第二种方式,实现 接口
方式是:
声明实现
Runnable
接口的类。该类然后实现 run
方法。然后可以分配该类的实例,在创建 Thread
时作为一个参数来传递并启动。
package com.zk.thread;
class Ticket implements Runnable{
private static int tick = 100;//一共100张票
public void run(){
while(true){
if(tick>0)//保证票数大于0
System.out.println(Thread.currentThread().getName()+" sell the "+tick--+" ticket");
}
}
}
public class TicketDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
两者比较:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
对于多线程中资源共享的部分,因为某个进程判断完之后没有返回结果就被冻结,当数据完成之后唤醒进程,获得的数据使用不合法。,此时需要对于共享资源部分使用同步代码块。
synchronized (obj) {
if(tick>0){//保证票数大于0
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sell the "+tick--+" ticket");
}
}