JAVA多线程

在java中要想实现多线程,有两种手段,一种是继承Thread类,另外一种是实现Runable接口。

1、继承Thread:

类名 extend Thread{
  public void run(){
  // other code…
  }
  public static void main(String[] args) {
    类名 t = new 类名();
    t.start();
  }
}

2、通过实现Runnable接口:
类名 implements Runnable{
  public void run(){
    // other code…
  }
  public static void main(String[] args) {
    类名 t = new 类名();
    new Thread(t,"线程名").start();
  }
}


线程
其实Thread中的run方法调用的是Runnable接口的run方法。

Thread和Runnable的区别:

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

/**
 * 
 * @author ZYL
 *
 */
public class ThreadShare extends Thread{
	
	private String name;
	private int ticket = 5;
	
	public ThreadShare(String name){
		this.name = name;
	}
	public void run() {
		for (int i = 0; i < 20; i++) {
			if (ticket > 0) {
				System.out.println(name+ "正在卖票"+this.ticket--);
			}
		}
	}
	
	public static void main(String[] args) {
		ThreadShare h1 = new ThreadShare("1号窗口:");
		ThreadShare h2 = new ThreadShare("2号窗口: ");
		ThreadShare h3 = new ThreadShare("3号窗口: ");
		h1.start();
		h2.start();
		h3.start();
	}
}

【运行结果】:
1号窗口:正在卖票5
3号窗口: 正在卖票5
2号窗口: 正在卖票5
2号窗口: 正在卖票4
2号窗口: 正在卖票3
2号窗口: 正在卖票2
2号窗口: 正在卖票1
3号窗口: 正在卖票4
1号窗口:正在卖票4
1号窗口:正在卖票3
3号窗口: 正在卖票3
1号窗口:正在卖票2
3号窗口: 正在卖票2
1号窗口:正在卖票1
3号窗口: 正在卖票1

假设这是一个买票程序,显然这是不对的。五张票卖了15次。

Runnable接口
class MyThread implements Runnable{

	private int ticket = 5;  //5张票

	public void run() {
		for (int i=0; i<=20; i++) {
			if (this.ticket > 0) {
				System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
			}
		}
	}
}
public class lzwCode {
	
	public static void main(String [] args) {
		MyThread my = new MyThread();
		new Thread(my, "1号窗口").start();
		new Thread(my, "2号窗口").start();
		new Thread(my, "3号窗口").start();
	}
}

【运行结果】:
1号窗口正在卖票5
2号窗口正在卖票4
3号窗口正在卖票2
1号窗口正在卖票3
2号窗口正在卖票1

这种结果才是我们期望的样子

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

线程的控制
1、线程睡眠  sleep
让正在执行的线程暂停,进入阻塞状态:Thread.sleep(时间(毫秒));
注意问题:sleep是静态方法,不能使用线程实例去调用。
2、线程让步  yield
让正在执行的线程暂停,不会进入阻塞状态,直接进入就绪状态。Thread.yield();
关于sleep()方法和yield()方的区别如下:

①、sleep方法暂停当前线程后,会进入阻塞状态,只有当睡眠时间到了,才会转入就绪状态。而yield方法调用后 ,是直接进入就绪状态,所以有可能刚进入就绪状态,又被调度到运行状态。

②、sleep方法声明抛出了InterruptedException,所以调用sleep方法的时候要捕获该异常,或者显示声明抛出该异常。而yield方法则没有声明抛出任务异常。

③、sleep方法比yield方法有更好的可移植性,通常不要依靠yield方法来控制并发线程的执行。

你可能感兴趣的:(java多线程)