线程的创建方式
方法一 .继承Thread类
//继承Thread类
public class MyThread extends Thread {
//重写Run方法
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i %2 ==0) {
System.out.println(getName()+":"+i);
}
}
}
}
class Test{
public static void main(String[] args) {
//创建实现类的对象
MyThread myThread =new MyThread();
//通过实现类的对象调用start()
myThread.start();
System.out.println("线程开始");
}
}
方法二 .实现Runnable 接口
/**
*创建一个实现了Runnable接口的类
*/
public class MyRunnable implements Runnable{
//实现类去实现Runnable中的抽象方法: run( )
@Override
public void run() {
for (int i = 0; i < 100;i++){
if(i%2==0){
System.out.println(Thread.currentThread().getName() +" :"+i);
}
}
}
}
class RunnableTest{
public static void main(String[] args) {
//创建实现类的对象
MyRunnable myRunnable = new MyRunnable();
//将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
Thread thread = new Thread(myRunnable);
//通过Thread类的对象调用start()
thread.start();
}
}
方法三.实现Callable 接口
public class MyCallableTest {
public static void main(String[] args) {
// 穿建callable接口的实现类的对象
Mycallable mycall =new Mycallable();
//将callable接口实现类的对象传到FutureTask构造器中,创建FUtureTask的对象
FutureTask future = new FutureTask(mycall);
//将FutureTask构造器的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()方法
new Thread(future).start();
{
try {
//get()返回值即为FutureTask构造器中callable实现类的重写call()的放回值
Object obj = future.get();
System.out.println("返回的参数"+obj);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
//实现Callable接口 Callable<>可以指定返回类型
class Mycallable implements Callable<Integer> {
private Integer number =100;
//重写call方法
@Override
public Integer call() throws Exception {
Integer sum = 0;
for (int i = 0; i < number.intValue(); i++) {
if(i%2==0){
System.out.println(Thread.currentThread().getName() +":"+i);
sum +=i;
}
}
return sum;
}
}
方法四.线程池创建
public class ThreadPoolTest{
public static void main(String[] args) {
//1.提供指定的线程数量的线程池
ExecutorService executorService =Executors.newFixedThreadPool(10);
//2.执行指定的线程草,需要提供实现Runnable接口或实现Callable接口的实现类的对象
//适用于基于Callable实现的
Future submit = executorService.submit(new MyThreadPool());
//适用于基于Runnable实现的
executorService.execute(new MyThreadPool1());
try {
//get()返回值即为FutureTask构造器中callable实现类的重写call()的放回值
Object o = submit.get();
System.out.println(o.toString());
}catch (Exception e) {
e.printStackTrace();
}
//关闭连接池
executorService.shutdown();
}
}
//实现Callable接口 Callable<>可以指定返回类型
class MyThreadPool implements Callable {
@Override
public Object call() throws Exception {
int sum =0;
for (int i = 0; i <100 ; i++) {
sum+=i;
}
return sum;
}
}
//实现Runnable接口
class MyThreadPool1 implements Runnable {
@Override
public void run() {
int sum =0;
for (int i = 0; i <100 ; i++) {
sum+=i;
}
System.out.println(sum);
}
}
线程池创建的方式
-
JDK 5.0起提供了线程池相关API:ExecutorService和 Executors。
-
ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor。
-
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池>。
-
Exicutors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池。
-
Executors.newFixedThreadPool(n);创建一个可重用固定线程数的线程池。
-
Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运。
-
Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
线程的生命周期
比较创建线程的两种方式。
- * 开发中:优先选择:实现Runnable接口的方式
- * 原因:1.实现的方式没有类的单继承性的局限性*
- * 2.实现的方式更适合来处理多个线程有共享数据的情况。
- *
- * 联系: public class Thread implements Runnable
- * 相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。*
Thread中的常用方法:
- start()∶启动当前线程;调用当前线程的run()
- run( ):通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
- currentThread():静态方法,返回执行当前代码的线程
- getName()∶获取当前线程的名字
- setName()∶设置当前线程的名字
- yield()∶释放当前cpu的执行权
- join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才 结束阻塞状态。
- stop():已过时。当执行此方法时,强制结束当前线程。
- sleep(Long millitime):让当前线程*睡眠"指定的milLitime毫秒。在指定的millitime毫秒时间内,当前
- isAlive():判断当前线程是否存活
线程的优先级:
- * MAXPRIORITY:10
- * MIN_PRIORITY:1
- * NORM_PRIORITY:5-->默认优先级2.如何获取和设置当前线程的优先级:
- * getPriority():获取线程的优先级
- * setPriority(int p):设置线程的优先级
- * 说明:高优先级的线程要抢占低优先级线程cpu的执毅权。但是只是从概率上讲,高优先级的线程高概率的情况下被执行。
- * 并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。