论坛首页 Java企业应用论坛

并发总结(1)

浏览 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也会花费在线程的调度上等等性能开销..

又写了一些,地址见上面哈
   发表时间:2010-05-16  
期待楼主更新
0 请登录后投票
   发表时间:2010-05-16  
不错不错 起到楼主的更新
0 请登录后投票
   发表时间:2010-05-16  
坐等楼主更新
0 请登录后投票
   发表时间:2010-05-16  
原来很少看字节码,原来这样可以更加理解原理,学习了。
期待lz更新。
0 请登录后投票
   发表时间:2010-05-17  
reilost 写道

比如一个方法
public class GetSequence {
	private int value;
	public int getValue(){
		return value++;
	}
}

在多线程执行的时候可能会出现调用方法得到的值是一样的情况..

调用方法得到的值一样有什么错.你是在两个线程new GetSequence,然后getValue()的吧
如果是这样两个对象的地址都不一样,根本不会发生冲突
0 请登录后投票
   发表时间:2010-05-17  
linvar 写道
reilost 写道

比如一个方法
public class GetSequence {
	private int value;
	public int getValue(){
		return value++;
	}
}

在多线程执行的时候可能会出现调用方法得到的值是一样的情况..

调用方法得到的值一样有什么错.你是在两个线程new GetSequence,然后getValue()的吧
如果是这样两个对象的地址都不一样,根本不会发生冲突


调用方法得到的值一样有什么错?这里LZ其实应该有个前提条件,在用GetSequence类获得唯一序号或者记录次数的时候,返回得到的值一样就不对了...
LZ是看《Java并发编程实践》做的总结吧?
0 请登录后投票
   发表时间: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过么?;)
0 请登录后投票
   发表时间:2010-05-17  
whg333 写道

LZ是看《Java并发编程实践》做的总结吧?


嗯,对哈,头段时间做的东西涉及很多并发,所以突击看了好多本书,写这个总结的时候,就用了那里提的那个例子..

另外,不能运行....额.....这....我菜鸟,不懂不能运行是指什么...求详解.
0 请登录后投票
   发表时间:2010-05-17  
写的什么啊,这也上主页。

请问管理员,主页文章是按什么排出来的啊,活跃度?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics