java多线程实现方式与死锁模拟

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();
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值