-
线程的基本概念:
线程是指程序执行的最小单元,是进程中的一个独立执行路径,能够并发执行,允许程序在同一时间执行多个任务。
单线程:
单线程就是进程中只有一个线程。单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
多线程:
由一个以上的线程组成的程序称为多线程程序。Java中,一定是从主线程开始执行(main方法),然后在主线程的某个位置创建并启动新的线程。
-
线程的特点:
1、并发性
2、共享性
3、轻量型
4、互相影响
-
实现线程的多种方式:
1、继承 java.lang.Thread 类(线程子类)
实现步骤:
定义一个类并继承Thread类,在该类中重写run()方法,在主线程中创建好了Theard类的实例,调用start()方法启动线程。
代码案例如下:
public class main {
public static void main(String[] args) {
System.out.println("主线程开始执行");
//创建子线程1
Thread thread1 = new Thread("线程1"){
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("[线程1]"+i);
}
}
};
thread1.start();//启动线程
System.out.println("主线程结束执行");
}
}
2、实现 java.lang.Runnable 接口(线程执行类)
实现步骤:
定义一个类来实现Runnable接口,实现run()方法,在主线程中创建MyRunnable的实例,并作为参数传递给Thread类的构造函数调用start()方法启动线程。
代码案例如下:
StringBuffer buffer = new StringBuffer();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(char c ='A';c<'F';c++) {
buffer.append(c);
}
}
});
t.start();
t.join();
System.out.println(buffer);
3、实现 java.util.concurrent.Callable 接口,允许子线程返回结果、抛出异常
实现步骤:
定义一个类来实现Callable接口,在主线程中创建MyCallable的实例,并作为参数传递给FuturTask类的构造函数来创建一个FuturTask对象,再将FuturTask对象作为参数传递给Thread类的构造函数调用start()方法启动线程。
代码案例如下:
StringBuffer buffer = new StringBuffer();
Thread t = new Thread(new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
String[] array = {"@","$","%","&","*"};
for (int i = 0; i < array.length; i++) {
buffer.append(array[i]);
}
return buffer.toString();
}
}));
t.start();
t.join();
System.out.println(buffer);
4、线程池
创建适合当前线程的线程池,提交多个任务给线程池,使用完线程池后进行关闭。
代码案例如下:
public class main {
public static void main(String[] args) {
//固定数量(10)的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
//不确定的线程数量
while(true) {
//向线程池提交一个执行任务(Runnable接口实现类对象)
//线程池分配一个"空闲线程"执行该任务
//如果没有空闲线程,则该任务进入“等待队列(工作队列)”
service.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("当前运行的线程名是"+Thread.currentThread().getName());
try {
Thread.sleep(1000);//休眠1000毫秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
}
-
总结
以上这四种方式都可以用来创建线程,具体选择那种方法取决于应用场景。