继承java.lang.Thread类创建线程是最简单的一种方法,也最直接。下面创建一个MyThread1类,继承Thread,重写其run()方法。并在main()方法中创建多个并发线程。
package simplethread;
public class MyThread1 extends Thread{
public MyThread1(String name){
super(name); //传递线程的名字
}
public static void main(String[] args){
for(int i=0;i<5;i++){
new MyThread1("thread"+i).start();
}
}
@Override
public void run(){
for(int i=0;i<20;i++){ //输出线程名字和i
System.out.println(this.getName()+":"+i);
}
}
}
这种创建方式,把线程执行的逻辑代码直接写在了Thread的子类中,这样根据线程的概念模型,虚拟CPU和代码混合在一起了。并且java是单继承机制,线程体继承Thread类后,就不能继承其他类了,线程的扩展受影响。
package simplethread;
public class MyThreadTarget implements Runnable{
public static void main(String[] args){
for(int i=0;i<5;i++){
//创建线程目标对象
Runnable r = new MyThreadTarget();
//把目标对象传递进Thread,即虚拟的CPU
new Thread(r,"thread"+i).start();
}
}
@Override
public void run(){
for(int i=0;i<20;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
从程序中可以看出线程目标对象和Thread分开了,并传递给了Thread。如果有比较复杂的数据要处理,可以在线程目标对象中引入数据。使用这种方式获得线程的名字就稍微复杂一些,需要使用到Thread中的静态方法,获得当前线程对象,然后再调用getName()方法。这种方式在较复杂的程序中用得比较普遍。
package pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestThreadPool{
public static void main(String args[])throws InterruptedException{
//在线程池中创建2个线程
ExecutorService exec = Executors.newFixedThreadPool(2);
//创建100个线程目标对象
for(int index=0;index<100;index++){
Runnable run = new Runner(index);
//执行线程目标对象
exec.execute(run);
}
//shutdown
exec.shutdown();
}
}
//线程目标对象
class Runner implements Runnable{
int index = 0;
public Runner(int index){
this.index = index;
}
@Override
public void run(){
long time = (long)(Math.random()*1000);
//输出线程的名字和使用目标对象及休眠的时间
System.out.println("线程:"+Thread.currentThread().getName()+"(目标对象"
+index+")"+":Sleeping"+time+"ms");
try{
Thread.sleep(time);
}catch(InterruptedException e){
}
}
}
执行结果的片断如下:
6.public static ExecutorService newSingleThreadExecutor()
创建一个使用单个 worker 线程的Executor,以无界队列方式来运行该线程。(只有一个Thread的线程池,循序的执行指定给它的每个任务)
7.public static ScheduledExecutorService newSingleThreadScheduledExecutor()
创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行(单一可排程Thread的线程池)