多线程
创建线程的方法有两种-一种是通过继承Thread类,另一种是通过实现Runnable创建线程。
实现Runnable接口
1】定义Runnable接口的实现类,重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体
2】创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象
3】通过调用线程对象的start()方法来启动线程
public class MyThread implements Runnable{ // 实现Runnable接口
public void run(){ // 覆写run()方法
for(int i=0;i<50;i++){
System.out.println(Thread.currentThread().getName()
+ "运行,i = " + i) ; // 取得当前线程的名字
}
}
public static void main(String args[]){
MyThread mt = new MyThread() ; // 实例化Runnable子类对象
Thread t = new Thread(mt,"线程"); // 实例化Thread对象
t.start() ; // 启动线程
for(int i=0;i<50;i++){
if(i>10){
try {
t.join() ; // 线程强制运行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Main线程运行 --> " + i) ;
}
}
继承Thread类
1】定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。
2】创建Thread子类的实例,也就是创建了线程对象
3】启动线程,即调用线程的start()方法
public class Tickets extends Thread {
public Tickets(String name){
super(name);
}
static int tickets = 20;
static Object obj = "obj";
public void run(){
while (tickets>0){
synchronized(obj){
if (tickets>0){
System.out.println(getName()+"卖出了"+(21-tickets)+"张票");
tickets--;
}else{
System.out.println("票卖完了");
}
}
try {
sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
实现Callable接口
而我们在使用Runnable时,会发现它缺少的一项功能,当线程终止时(即run()完成时),我们无法使线程返回结果。为了支持此功能,Java中提供了Callable接口。另外Callable的call ()方法还能抛出异常。
- 为了实现Runnable,需要实现不返回任何内容的run()方法,而对于Callable,需要实现在完成时返回结果的call()方法。
- 请注意,不能使用Callable创建线程,只能使用Runnable创建线程。
- 另一个区别是call()方法可以引发异常,而run()则不能。
- 为实现Callable而必须重写call方法。
public class MyCallable implements Callable {
private int id;
public MyCallable(int id){
super();
this.id = id;
}
@Override
public String call() throws Exception {
System.out.println(">>>" + id + "任务启动");
Map<String, Object> map = new HashMap<>();
map.put("id",id);
String idString = map.get("id").toString()+"aa";
System.out.println(">>>" + id + "任务进行中");
System.out.println(">>>" + id + "任务结束");
return idString;
}
}
结合Future获取返回值
阿里不允许使用 ExecutorService去创建线程池
public static void main(String[] args) {
MyCallable myCallable;
//ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future> list = new ArrayList<>();
ThreadPoolExecutor pool = new ThreadPoolExecutor(5,10,60,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(10));
for (int i = 0;i<10; i++){
myCallable = new MyCallable(i);
Future future = pool.submit(myCallable);
list.add(future);
}
for (Future f : list) {
// 从Future对象上获取任务的返回值,并输出到控制台
try {
System.out.println(">>>任务返回值: " + f.get().toString());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
pool.shutdown();
}