1.有两种方法实现创建线程
a)继承Thread类
子类需要重载Thread类中的run()方法,这样子类就能作为线程启动了。
例如:
/*
* MyThread.java
*
* */
public class MyThread extends Thread {
private int tickets = 10;
public MyThread() {
super();
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0; i<= tickets; i++){
System.out.println("第" + i + "张票已卖出!");
}
System.out.println("票已卖完!");
}
}
使用的时候直接调用Thread类的start函数即可:
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建线程
MyThread thread1 = new MyThread();
//启动线程
thread1.start();
}
}
输出结果如下:
b)实现Runnable接口
此类需要通过实现Runnable接口中run方法,这种方式创建线程的时候,需要把此类通过参数的形式传给Thread类来实现。
例如:
/*
* MyRunnable.java
* */
public class MyRunnable implements Runnable {
private int tickets = 10;
MyRunnable(){}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 1;i <= 10; i++){
if(tickets > 0){
System.out.println("第" + tickets-- + "张票卖出!");
}
}
System.out.println("票已卖完");
}
}
线程的创建过程如下:
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建线程
//MyThread thread1 = new MyThread();
//启动线程
//thread1.start();
//创建实现了Runnable接口的类实例
MyRunnable r = new MyRunnable();
//把创建的实例r做为参数传给Thread的构造函数,创建线程
Thread thread2 = new Thread(r);
//启动线程
thread2.start();
}
}
它运行结果如下:
2.多线程
为了更好的辨别输出结果属于哪个线程的,我们在线程类中增加一个线程id的输出信息,把输出语句替换为:
System.out.println("线程" + this.getId() +":第" + i + "张票已卖出!");
然后我们看下继承Thread的类来实现的多线程:
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建线程1
MyThread thread1 = new MyThread();
//启动线程1
thread1.start();
//创建线程2
MyThread thread2 = new MyThread();
//启动线程2
thread2.start();
}
}
它的输出结果:
有结果可知:通过继承Thread类创建的每个线程对象中的run方法在处理自己的实例变量tickets。
这时我们可能更需要的是多线程处理同一个数据tickets,这时就需要使用继承了Runnable的类来处理了。
这时可以直接如下创建线程:
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyRunnable r = new MyRunnable();
//把创建的实例r做为参数传给Thread的构造函数,创建线程
Thread thread1 = new Thread(r);
//启动线程
thread1.start();
Thread thread2 = new Thread(r);
//启动线程
thread2.start();
}
}
来看下运行结果:
由结果可知:通过runnable实现的多线程可以实现多线程对同一资源的共享访问。
最后附上Thread.class中关于线程的说明:
/**
* A <i>thread</i> is a thread of execution in a program. The Java
* Virtual Machine allows an application to have multiple threads of
* execution running concurrently.
* <p>
* Every thread has a priority. Threads with higher priority are
* executed in preference to threads with lower priority. Each thread
* may or may not also be marked as a daemon. When code running in
* some thread creates a new <code>Thread</code> object, the new
* thread has its priority initially set equal to the priority of the
* creating thread, and is a daemon thread if and only if the
* creating thread is a daemon.
* <p>
* When a Java Virtual Machine starts up, there is usually a single
* non-daemon thread (which typically calls the method named
* <code>main</code> of some designated class). The Java Virtual
* Machine continues to execute threads until either of the following
* occurs:
* <ul>
* <li>The <code>exit</code> method of class <code>Runtime</code> has been
* called and the security manager has permitted the exit operation
* to take place.
* <li>All threads that are not daemon threads have died, either by
* returning from the call to the <code>run</code> method or by
* throwing an exception that propagates beyond the <code>run</code>
* method.
* </ul>
* <p>
* There are two ways to create a new thread of execution. One is to
* declare a class to be a subclass of <code>Thread</code>. This
* subclass should override the <code>run</code> method of class
* <code>Thread</code>. An instance of the subclass can then be
* allocated and started. For example, a thread that computes primes
* larger than a stated value could be written as follows:
* <p><hr><blockquote><pre>
* class PrimeThread extends Thread {
* long minPrime;
* PrimeThread(long minPrime) {
* this.minPrime = minPrime;
* }
*
* public void run() {
* // compute primes larger than minPrime
* . . .
* }
* }
* </pre></blockquote><hr>
* <p>
* The following code would then create a thread and start it running:
* <p><blockquote><pre>
* PrimeThread p = new PrimeThread(143);
* p.start();
* </pre></blockquote>
* <p>
* The other way to create a thread is to declare a class that
* implements the <code>Runnable</code> interface. That class then
* implements the <code>run</code> method. An instance of the class can
* then be allocated, passed as an argument when creating
* <code>Thread</code>, and started. The same example in this other
* style looks like the following:
* <p><hr><blockquote><pre>
* class PrimeRun implements Runnable {
* long minPrime;
* PrimeRun(long minPrime) {
* this.minPrime = minPrime;
* }
*
* public void run() {
* // compute primes larger than minPrime
* . . .
* }
* }
* </pre></blockquote><hr>
* <p>
* The following code would then create a thread and start it running:
* <p><blockquote><pre>
* PrimeRun p = new PrimeRun(143);
* new Thread(p).start();
* </pre></blockquote>
* <p>
* Every thread has a name for identification purposes. More than
* one thread may have the same name. If a name is not specified when
* a thread is created, a new name is generated for it.
* <p>
* Unless otherwise noted, passing a {@code null} argument to a constructor
* or method in this class will cause a {@link NullPointerException} to be
* thrown.