【深入浅出java多线程】--基础准备篇
来源:互联网 发布:linux 启动进程 start 编辑:程序博客网 时间:2024/05/16 06:47
一,简单回顾
线程的两种实现方式:
1.继承Thread类(不推荐)–其实Thread类本身就是实现了Runnable接口
public class MyThread extends Thread{ private static int i= 0; public MyThread(){ i++; } @Override public void run() { System.out.println("创建第"+i+"个线程"); }}
2.实现Runnable接口
public class MyThread { public static void main(String[] args) { System.out.println("主线程ID:" + Thread.currentThread().getId()); new Thread(new MyRunnable()).start(); }}class MyRunnable implements Runnable { @Override public void run() { // 只关心要做的任务 System.out.println("子线程ID:" + Thread.currentThread().getId()); }}
或者直接这样:
public static void main(String[] args) { System.out.println("主线程ID:" + Thread.currentThread().getId()); Runnable runnable = new Runnable() { @Override public void run() { System.out.println("子线程ID:" + Thread.currentThread().getId()); } }; new Thread(runnable).start(); }
结果都是:
主线程ID:1
子线程ID:9
二,线程状态
**- sleep,yield和wait的区别:
- sleep和yield是Thread类的静态方法,wait是Object类中定义的方法.
- Thread.sleep不会导致锁行为的改变, 如果当前线程是拥有锁的, 那么Thread.sleep不会让线程释放锁.
- wait()的作用是让当前线程由“运行状态”进入到“等待(阻塞)状态”,并释放同步锁。
- 而yield()的作用是让步,它让当前线程离开“运行状态”,进入到“就绪状态”。而且yield()方法不会释放锁。yield()只能使同优先级或更高优先级的线程有执行的机会。
- wait可以用notify/notifyAll方法唤醒,如果调用的是await,需要调用signal/signalAll来唤醒,两者只是名字不同,内部实现完全一样。**
三,使用Callable+Future/FutureTask
与Runnable不同的是,Callable**有返回结果**,其他用法一样,线程常用类都在java.util.concurrent并发包内。
public interface Callable<V> { //此接口里只有这一个方法 V call() throws Exception;//注意到,接口的参数类型就是方法的返回类型
@Overridepublic Object call() throws Exception { // 我们可以看到返回的是Object,call与run方法内部实现一样,换了名字而已 //do something... return null;}
FutureTask实现了RunnableFuture接口,后者又分别继承了Runnable和Future接口,在线程中,用Future来接收线程的执行结果,jdk1.7中提供了可以操作线程或者查看线程状态的5个方法,分别是cancel,isCancelled,isDone,get和get的重写。但是其有个缺点,当多线程时,并不知道哪个线程先结束,为了提高性能,便有了FutureTask。它可以准确获取线程执行完成后返回的结果,此功能得益于它有一个回调函数protected void done(),当任务结束时,该回调函数会被触发。具体做什么,可以自己重载去实现。
e.g
package com.wz.test;import java.util.Random;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.FutureTask;import java.util.concurrent.TimeUnit;public class AboutFuture { public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool();//稍后分析Executors的线程池框架 Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { // TODO Auto-generated method stub Random random = new Random(); TimeUnit.SECONDS.sleep(random.nextInt(10)); return Thread.currentThread().getName(); } }; for (int i = 0; i < 6; i++) { AboutFutureTask futureTask = new AboutFutureTask(callable); Future<?> future=executor.submit(futureTask); System.out.println("返回结果future:" + future);//返回结果future:java.util.concurrent.FutureTask@5193b022,这里只列出一条结果 } executor.shutdown(); }}class AboutFutureTask extends FutureTask<String> { public AboutFutureTask(Callable<String> callable) { //此处构造器是必需的 super(callable); } @Override protected void done() {//重写FutureTask中的done()可以做自己想做的任务或者获取线程的信息 try { System.out.println(get() + "当前线程已执行完毕!"); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } }}
执行结果:
pool-1-thread-2当前线程已执行完毕!
pool-1-thread-5当前线程已执行完毕!
pool-1-thread-3当前线程已执行完毕!
pool-1-thread-4当前线程已执行完毕!
pool-1-thread-1当前线程已执行完毕!
pool-1-thread-6当前线程已执行完毕!
四,Thread其他常用方法(已过时的不列举)
- public static native Thread currentThread();//返回当前运行的线程对象
public static void yield();//推荐静态调用;暂停当前线程对象,恢复到可执行状态,自己仍可以再次执行;
public final native boolean isAlive();//线程是否处于活动状态
public final void join();//让其他线程等待该线程结束
public final void join(long millis);//让其他线程等待该线程结束,最多等millis毫秒
关于线程中断:
public void interrupt() ;//向线程发出中断请求。
public static boolean interrupted() ;//测试当前线程是否被中断。值得注意的是,这是个静态方法,调用它时会产生副作用—重置当前线程的中断状态为false,也就是说如果某个线程在中断情况下,调用了此方法,会将此线程唤醒。但是换个角度,如果当notifyAll()不起作用,也就是锁标志等待池中没有任何活动线程时,可以调用该方法,激活一个线程,从而去拯救其他线程。
public boolean isInterrupted() ;//测试线程是否被终止。此调用不会改变线程状态。
- 【深入浅出java多线程】--基础准备篇
- Java基础---深入浅出多线程
- Java高并发编程之第一阶段,多线程基础深入浅出
- Java高并发编程之第一阶段,多线程基础深入浅出
- 深入浅出java多线程
- 深入浅出Java多线程程序设计
- 深入浅出Java多线程程序设计
- 深入浅出Java多线程程序设计
- 深入浅出JAVA多线程(一)
- 深入浅出Java多线程程序设计
- Java 多线程深入浅出
- 深入浅出Java多线程编程
- 深入浅出Java多线程程序设计
- 慕课网 深入浅出java多线程
- 深入浅出java多线程
- 深入浅出Java多线程
- Java多线程--基础篇
- java多线程基础篇
- SSL 1217——删边
- Java UDP 重发机制
- poj3468(区间更新)
- 正则表达式
- Design Pattern(5)-Visitor Pattern
- 【深入浅出java多线程】--基础准备篇
- 安卓开发之详解getChildFragmentManager和getsupportFragmentManager和getFragmentManager详解
- 50个必备的实用jQuery代码段
- ref 和 out
- 在C语言中,double、long、unsigned、int、char类型数据所占字节数
- 将字符串中的中文标点替换成英文标点
- 户外监测让谁来做最可靠?
- JS字符串操作
- postMessage实现跨域密码代添