------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
方法1:继承Thread类
继承Thread类,重写run方法,把需要被线程执行的代码写到run()方法中
public class MyThread extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + "---" + x);
}
}
}
创建Thread的子类对象,调用类的start静态方法开启线程
public static void main(String[] args) throws InterruptedException {
MyThread mt = new MyThread();
MyThread mt2 = new MyThread();
mt.start();
mt2.start();
}
}
线程的常用方法
1.给线程命名
public final void setName(String name)
2.获取当前的线程名
public final String getName()
3.获取和设置线程的优先级
public final int getPriority()
public final void setPriority(int newPriority)
4.线程加入(等待该线程终止)
public final void join()
5.线程礼让
public static void yield()
6.针对不是Thread类的子类中如何获取线程对象名称呢?
public static Thread currentThread():返回当前正在执行的线程对象
Thread.currentThread().getName()
7.守护线程
public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java 虚拟机退出。
该方法必须在启动线程前调用。
方法2:实现Runnable接口
A:使类实现Runnable接口,重写run方法,把需要线程执行的代码写入run方法中
import java.util.Date;
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程开始执行"+new Date());
try {
Thread.sleep(10000);
for(int x=0;x<100;x++){
System.out.println(Thread.currentThread().getName()+"---"+x);
}
} catch (InterruptedException e) {
System.out.println("线程被终止");
//e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行完毕"+new Date());
}
}
B:创建类对象,以便作为参数传递
C:创建Thread对象,并把B步骤的对象最为参数使用 D:通过Thread对象的start方法开启线程
优点: 开启多个线程只需创建一个参数对象
public class MyThreadDemo2 {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread t = new Thread(my, "王力宏");
Thread t2 = new Thread(my,"刘亦菲");
t.start();
t2.start();
//3妙后关闭线程
try {
Thread.sleep(3000);
t2.stop(); //改方法已经过时,该方法停止线程
t.interrupt();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
方法3:利用线程池开启线程
执行原理:
A:利用Executors的静态方法newFixedThreadPool(int nThreads)创建一个线程池
public static ExecutorService newFixedThreadPool(int nThreads)
创建一个可重用固定线程数的线程池
查API可以看出,返回值ExecutorService是一个接口,所以实际返回值应该是其具体实现类
B:ExecutorService的主要方法有:
void shutdown() 关闭线程池
Future submit(Callable task) 提交一个返回值的任务用于执行
该方法可以得到一个返回值
Future> submit(Runnable task) 提交一个 Runnable 任务用于执行
由此可知,线程池可以执行Runnable对象或者Callable对象代表的线程
只需传递一个实现了该接口的实例即可
写一个实现了Callable接口的实例
import java.util.concurrent.Callable;
/*
需求:写一个1-n的求和线程
*/
public class CallableSum implements Callable {
private int number;
public CallableSum(int number) {
this.number = number;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int x = 1; x <= number; x++) {
sum += x;
}
return sum;
}
}
再写一个实现了Runnable接口的实例
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int x=0;x<100;x++){
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
C:调用submit方法开启线程。
D:调用shutdown方法关闭线程池
public class ThreadPool {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(2);
//传递Runnable的实现类开启线程
pool.submit(new MyRunnable());
Future f = pool.submit(new CallableSum(100));
Integer i = f.get();
System.out.println(i);
//关闭线程池
pool.shutdown();
}
}