java 多线程使用的时候有
1.实现Runnable接口 资源可以共享
2.继承Thread类 资源可以共享
3.实现Callable接口 实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果,Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
ExecutorService、Callable、Future三个接口实际上都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,有了这种特征就不需要再为了得到返回值而大费周折了。而且自己实现了也可能漏洞百出。
可返回值的任务必须实现Callable接口。类似的,无返回值的任务必须实现Runnable接口。
执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。
注意:get方法是阻塞的,即:线程无返回结果,get方法会一直等待。
再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。
Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 死锁
*
* @author xuzhao
*
*/
public class DeadLock {
//定义两个对象
private Object oa = new Object();
private Object ob = new Object();
/**
* 方法一: 运行之后 先使用 对象oa 休眠2秒去使用 对象 ob
*/
public void one() {
synchronized(oa) {
System.out.println("我正在使用 oa");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(ob) {
System.out.println("我正在使用 ob");
}
System.out.println("我用了 oa ob");
}
}
/**
* 方法二: 运行之后 先使用 对象ob 休眠2秒去使用 对象 oa
*/
public void two() {
synchronized(ob) {
System.out.println("我正在使用 ob");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(oa) {
System.out.println("我正在使用 oa");
}
System.out.println("我用了 ob oa");
}
}
public static void main(String[] args) {
/*
DeadLock.ThreadA A = new ThreadA(new DeadLock());
ExecutorService service = Executors.newCachedThreadPool();
Future<Integer> future = service.submit(A) ;
try {
System.out.println(future.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
DeadLock dead = new DeadLock(); //一定要定义线程 使用 start()才是开启多线程
Thread A = new Thread(new ThreadA(dead));
Thread B = new Thread(new ThreadB(dead));
//此处不可以调用 run(),调用run run内的代码也会被执行,程序是顺序执行,不会启动多线程跑 Thread.start();是开启一个新线程的函数
A.start();
//A.run();
System.out.println("---a");
B.start();
//B.run();
System.out.println("b---");
}
/* private static class ThreadA implements Callable<Integer>{
private DeadLock da;
public ThreadA(DeadLock da) {
super();
this.da = da;
}
@Override
public Integer call() throws Exception {
System.out.println("调用了");
da.one();
return 0;
}
}*/
private static class ThreadA implements Runnable{//extends Thread{
private DeadLock da;
public ThreadA(DeadLock da) {
super();
this.da = da;
}
@Override
public void run() {
da.one();
}
}
private static class ThreadB implements Runnable{//extends Thread{
private DeadLock db;
public ThreadB(DeadLock db) {
super();
this.db = db;
}
@Override
public void run() {
db.two();
}
}
}