浏览 6774 次
锁定老帖子 主题:并发总结(1)
精华帖 (5) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2010-05-15
最后修改:2010-05-17
并发总结(2)
Java在顺序型语言的基础上提供对线程的支持.线程机制是在由执行程序表示的单一进程中创建任务.Java中的线程机制是抢占式的,调度机制会周期性的中断线程,将上下文切换到另一个线程,从而为每一个线程都系统时间片,使每个线程都会分到数量合理的时间去驱动他的任务. 1.使用线程 线程可以驱动任务,所以我们需要描述一个任务. 实现Runnable接口.编写run()方法,但是这样一个方法并没有产生线程的能力,要实现线程行为,就必须把这个任务附到一个线程上.这个方式就是把他提交给Thread.. 执行thread的start方法后是迅速返回的 public static void main(String[] args) { Thread t1=new Thread(new TestRunnable()); t1.start(); }生成的class中,我们可以看到是这样的 invokevirtual return Runnable是独立任务,没有任何返回值,如果希望得到返回值,可以使用callable接口.但是这个必须使用executorService的submit来调用.. public class TestCallable implements Callable<String> { public String call() throws Exception { Thread.sleep(50); return Thread.currentThread().getName(); } } public static void main(String[] args) { ExecutorService executorService= Executors.newCachedThreadPool(); List<Future<String>> results=new ArrayList<Future<String>>(); for(int i=0;i<10;i++){ results.add(executorService.submit(new TestCallable())); } for(Future<String> s:results){ try { System.out.println(s.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } 在使用future的get方法时如果线程还没有执行完成会阻塞知道结果返回.可以用isDone来查看是否完成. 另外实现线程的方法,直接继承Thread写run方法,然后调用start..Thread的start方法是直接调用run方法的. 2.线程的风险. 使用线程的风险如同他的好处一样不少..=.=真是个双刃剑哈. 首要的风险,就是大家都知道的安全危险. 比如一个方法 public class GetSequence { private int value; public int getValue(){ return value++; } } 在多线程执行的时候可能会出现调用方法得到的值是一样的情况.. 这个时候就会得到相同的值..当然,因为存在重排序的可能,也许情况会更烂哈. 这种危险就是竞争条件.因为线程间共享相同的内存地址空间,而且并发运行,他们就有可能访问或者修改其他线程正在使用或者修改的变量.. 为了预防这种风险,就需要同步机制来协调访问.. 比如,加上一个synchronized关键字. public class GetSequence { private int value; public synchronized int getValue(){ return value++; } } 还有一种危险就是活跃度危险.当一个活动进入到一种他永远无法继续执行的时候,就发生了活跃度失败. 主要有我们常听说的,死锁,还有活锁,饥饿. 多线程可以给我们带来一些性能上的好处,也同样可以带来一些性能上的危险..比如上下文切换时,频繁切换会给系统带来巨大的开销..比如保存,回复线程的上下文,cpu也会花费在线程的调度上等等性能开销.. 又写了一些,地址见上面哈 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-05-16
期待楼主更新
|
|
返回顶楼 | |
发表时间:2010-05-16
不错不错 起到楼主的更新
|
|
返回顶楼 | |
发表时间:2010-05-16
坐等楼主更新
|
|
返回顶楼 | |
发表时间:2010-05-16
原来很少看字节码,原来这样可以更加理解原理,学习了。
期待lz更新。 |
|
返回顶楼 | |
发表时间:2010-05-17
reilost 写道 比如一个方法 public class GetSequence { private int value; public int getValue(){ return value++; } } 在多线程执行的时候可能会出现调用方法得到的值是一样的情况.. 调用方法得到的值一样有什么错.你是在两个线程new GetSequence,然后getValue()的吧 如果是这样两个对象的地址都不一样,根本不会发生冲突 |
|
返回顶楼 | |
发表时间:2010-05-17
linvar 写道 reilost 写道 比如一个方法 public class GetSequence { private int value; public int getValue(){ return value++; } } 在多线程执行的时候可能会出现调用方法得到的值是一样的情况.. 调用方法得到的值一样有什么错.你是在两个线程new GetSequence,然后getValue()的吧 如果是这样两个对象的地址都不一样,根本不会发生冲突 调用方法得到的值一样有什么错?这里LZ其实应该有个前提条件,在用GetSequence类获得唯一序号或者记录次数的时候,返回得到的值一样就不对了... LZ是看《Java并发编程实践》做的总结吧? |
|
返回顶楼 | |
发表时间:2010-05-17
最后修改:2010-05-17
linvar 写道 reilost 写道 比如一个方法 public class GetSequence { private int value; public int getValue(){ return value++; } } 在多线程执行的时候可能会出现调用方法得到的值是一样的情况.. 调用方法得到的值一样有什么错.你是在两个线程new GetSequence,然后getValue()的吧 如果是这样两个对象的地址都不一样,根本不会发生冲突 同意,这个例子是有问题的,加上sync 的关键字也不会work,楼主test过么?;) |
|
返回顶楼 | |
发表时间:2010-05-17
whg333 写道 LZ是看《Java并发编程实践》做的总结吧? 嗯,对哈,头段时间做的东西涉及很多并发,所以突击看了好多本书,写这个总结的时候,就用了那里提的那个例子.. 另外,不能运行....额.....这....我菜鸟,不懂不能运行是指什么...求详解. |
|
返回顶楼 | |
发表时间:2010-05-17
写的什么啊,这也上主页。
请问管理员,主页文章是按什么排出来的啊,活跃度? |
|
返回顶楼 | |