获取线程的名称,获取所有线程,线程问题开启和关闭20190227

1.获取线程的名称

参考:https://blog.csdn.net/luyaran/article/details/80595772  

public class Main extends Thread {
   public static void main(String[] args) {
      Main t1 = new Main();
      t1.setName("thread1");
      t1.start();
      ThreadGroup currentGroup = 
      Thread.currentThread().getThreadGroup();
      int noThreads = currentGroup.activeCount();
      Thread[] lstThreads = new Thread[noThreads];
      currentGroup.enumerate(lstThreads);
      for (int i = 0; i < noThreads; i++)
      System.out.println("线程号:" + i + " = " + lstThreads[i].getName());
   }
}


2.线程基本方法:

名称    说明
public Thread()    构造一个新的线程对象(Thread类的构造函数),默认名为Thread-n,n是从0开始递增的整数
public Thread(Runnable target)    构造一个新的线程对象,以一个实现Runnable接口的类的对象为参数,默认名为Thread-n,n是从0开始递增的整数(哈哈哈,从此处构造函数可以看出创建线程的两种不同方式,处处点题,我真机智!)
public Thread(String name)    构造一个线程对象,并同时指定线程名
public static Thread currentThread()    返回一个当前正在运行的线程对象
public static void yield()    使当前线程对象暂停,允许别的线程开始运行(注:yield:屈服)
public static void sleep(long millis)    使当前线程暂停运行指定毫秒数,但此线程并不失去已获得的锁
public void start()    启动线程,JVM将调用此线程的run方法,结果是将同时运行两个线程,当前线程和执行run方法的线程
public void run()    Thread的子类应该重写此方法,内容应为该线程应执行的任务
public final void stop()    停止线程运行,释放该线程占用的对象锁

public void interrupt()    中断此线程

public final void join()    如果启动了线程A,调用join方法将等待线程A死亡才能继续执行当前线程
public final void join(long millis)    如果此前启动了线程A,调用join方法将等待指定毫秒数或线程A死亡才能继续执行当前线程
设置线程优先级
public final void setPriority( int newPriority)    设置线程优先级
public final void setDaemon(Boolean on)    设置是否为后台线程,如果当前运行线程均为后台线程则JVM停止运行。这个方法必须在start()方法前使用(注:daemon:后台程序)
public final void checkAccess()    判断当前线程是否有权力修改调用此方法的线程
public void setName(String name)    更改本线程的名称为指定参数
public final boolean isAlive()    测试线程是否处于活动状态,如果线程被启动并且没有死亡则返回true

3.获取当前运行的所有线程

 下面的静态方法可以用数组返回 Java VM 中当前运行的所有线程
public static Thread[] findAllThreads() {
ThreadGroup group = 
Thread.currentThread().getThreadGroup();
ThreadGroup topGroup = group;

        // 遍历线程组树,获取根线程组
while ( group != null ) {
topGroup = group;
group = group.getParent();
}
        // 激活的线程数加倍
int estimatedSize = topGroup.activeCount() * 2;
Thread[] slackList = new Thread[estimatedSize];
        //获取根线程组的所有线程
int actualSize = topGroup.enumerate(slackList);
// copy into a list that is the exact size
Thread[] list = new Thread[actualSize];
System.arraycopy(slackList, 0, list, 0, actualSize);
return list;

4.Java创建并执行线程的四种方法

参考:原文:https://blog.csdn.net/li_mengjun/article/details/78159827 

java里面创建线程有四种方式: 
无返回: 
1. 实现Runnable接口,重写run(); 
2. 继承Thread类,重写run(); 

有返回: 
1. 实现Callable接口,重写call(),利用FutureTask包装Callable,并作为task传入Thread构造函数; 
2. 利用线程池;

1. 继承Thread类,重写run(); 
创建:创建线程只需要继承Thread类,然后在run方法里写下线程要实现的任务即可; 
这里写图片描述 

调用:通过调用start方法来启动线程而不能直接调用run方法。 
这里写图片描述

① Thread类本质上是实现了Runnable接口,Thread对象代表一个线程的实例。 
② Runnable接口只有一个抽象的run()方法。 
③ 启动线程的唯一方法就是通过Thread类的start()实例方法。 
start()方法是一个native方法,它将启动一个新线程,并执行run()方法。 
⑤ 自定义类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。 
2. 创建任务,实现Runnable接口,重写run()。(受欢迎) 
因为Java只能单继承,继承了Thread类就不能再继承别的类了所以实现继承更推崇的是让线程类实现Runnable接口。 
2.这里写图片描述 

将Runnbale作为参数传入Thread的构造函数,创建Thread. 
这里写图片描述 

 3.Callable接口只包含抽象方法V call()。 

这里写图片描述 

利用Callable接口创建并启动新线程的步骤: 
① 定义MyClass实现Callable接口;Class MyClass implements Callable 
② 重写call(),将执行的代码写入; 
③ 创建FutureTask的对象;FutureTask中定义了run(),run()内部调用了call(),并保存了call()的返回值;FutureTask futuretask = new FutureTask(newMyClass()); 
④ 创建Thread的对象;Thread thread = new Thread(futuretask);//传入参数Runnable接口 
⑤ 启动线程;thread.start();[图片] 
⑥ 可通过FutureTask类的get()方法获得线程执行结束后的返回值,即call的返回值。futuretask.get();

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyThread {

    public static void main(String[] args) throws InterruptedException {
        FutureTask<Integer> task = new FutureTask<Integer>(new CallableImpl());
        Thread thread = new Thread(task);
        thread.start();
        try {
            System.out.println("task.get() returns " + task.get());
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class CallableImpl implements Callable<Integer> {

    private static Integer value = 0;

    @Override
    public Integer call() throws Exception {
        System.out.println("执行call方法之前 value = " + value);
        value = value.intValue() + 1;
        System.out.println("执行call方法之后 value = " + value);
        return value;
    }
}

运行结果: 
执行call方法之前 value = 0 
执行call方法之后 value = 1 
task.get() returns 1 
4. 通过线程池来创建线程 
① new ThreadPoolExecutor(…); 
② 创建任务Task implements Callable,重写run()方法; 
③ 通过线程池的execute()或submit()将任务command传入线程池; 
④ 获取返回值: 
1) 实现Callable接口,重写call()方法 
class CallableImpl implements Callable 
2) 定义线程池 
ThreadPoolExecutor executor 
3) 利用submit()方法提交任务 
Future<?> future = executor.submit(new CallableImpl()); 
5) 利用FutureTask类get()方法获取返回值 
res = task.get(); 
这里future申明为Future对象,但是它是由FutureTask实现的,也可以直接申明为FutureTask future:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MyThreadPool {
    public static void main(String[] args) throws InterruptedException, ExecutionException {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(20));
        Future task;
        for (int i = 0; i < 5; i++) {
            task = executor.submit(new CallableImpl());
            System.out.println("线程返回结果:" + task.get());
        }
        executor.shutdown();
    }
}

class RunnableImpl implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("hhh");
        System.out.println(Thread.currentThread().getName());
    }
}
运行结果: 
执行call方法之前 value = 0 
执行call方法之后 value = 1 
线程返回结果:1 
执行call方法之前 value = 1 
执行call方法之后 value = 2 
线程返回结果:2 
执行call方法之前 value = 2 
执行call方法之后 value = 3 
线程返回结果:3 
执行call方法之前 value = 3 
执行call方法之后 value = 4 
线程返回结果:4 
执行call方法之前 value = 4 
执行call方法之后 value = 5 
线程返回结果:5

总结: 
线程的创建有四种方式:主要分为有返回和无返回,具体根据使用场景来选择。 
1. 如果不需要返回且线程数量小,则建议采用实现Runnable接口,重写run()的方式; 
2. 如果需要返回且线程数量小,则建议采用实现Callable接口,重写call(),利用FutureTask包装成一个Runnable,再作为参数传入Thread的构造方法的方式创建线程; 
3. 如果线程数量较多,则建议采用线程池方式创建:execute提交任务实现无返回操作,submit提交任务实现有返回操作。

补充:FutureTask 
JDK1.8中FutureTask实现了RunnableFuture,而RunnableFuture顾名思义就是Runnable接口和Future接口的结合体。因此,FutureTask对象可以作为Runnable对象来用,比如

    Thread thread = new Thread(new FutureTask<V>());
1
也可以作为Future来用。这就是Java的有魅力的地方。。。

    public class FutureTask<V> implements RunnableFuture<V>
    public interface RunnableFuture<V> extends Runnable, Future<V> {
        void run();
    }

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值