Chinaunix首页 | 论坛 | 博客
  • 博客访问: 886683
  • 博文数量: 380
  • 博客积分: 3495
  • 博客等级: 中校
  • 技术积分: 3996
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-02 09:35
文章分类

全部博文(380)

文章存档

2015年(2)

2014年(5)

2013年(9)

2012年(9)

2011年(67)

2010年(103)

2009年(182)

2008年(3)

我的朋友

分类: Java

2010-07-05 21:46:09

JAVA线程研究

Java的线程是由一个Thread类与一个接口Runnable引入的。
当然Thread implements Runnable
下面是具体的声明。
public class Thread
extends
implements

下面是一段取自Thread.java的代码
public synchronized void start() {
        /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
    }

    private native void start0();
也就是说start是直接调用star0的,
不过start0是由JVM来直接调用本地的实现的。
也就是说,start0会调用run()这个方法的。
下面的代码也是取自Thread.java
 public void run() {
    if (target != null) {
        target.run();
    }
  }
当然了target就是runnable的一个实例,也就是说Thread是调用Runnable接口来的。
这也就是
new Thread() {
  public void run() {

的方法关联的东西吧。

再有就是Thread的状态。一般来讲Thread的状态是分成四种的,准备,执行,等待,终止四个,实际上呢?
Thread.java中有一个  public enum State 的枚举类,它有如下几个状态
NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED。
很明显除了等待有三个具体状态外,其它的都是一对一的。

接下来就是JAVA线程中的数据同步。
public class SynchronizedCounter {
private int c = 0;

public synchronized void increment() {
c++;
}

public synchronized void decrement() {
c--;
}

public synchronized int value() {
return c;
}
}
上面这个类的方法很明显都是用关键字synchronized修饰过的,也就是说这些方法都会保证再相应的方法
被调用时不会有任何其它的方法被调用到。这样变量c就会总按些方法的处理进行变化,而不会出现异常。

如果把synchronized去掉,就会有各种奇怪的现象发生了。

当然了同步也可以在一个小语句块中加入。
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
这样,nameCount跟lastName都是相同的了,毕竟后面的nameList做为一个容器可以在多线程的环境下
可以被同时放入与取出某些内容更合乎我们世界的客观规律嘛。

Atomic Access
JAVA语言中默认支持下面的原子操作。
  • Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
  • Reads and writes are atomic for all variables declared volatile (including long and double variables).
也就是说读写引用类型的变量 与除了long,double以后的基本类型变量是原子的操作。
而对于所有声明为volatile的变量都是原子操作。

下面是一段死锁代码。
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s has bowed back to me!%n",
this.name, bower.getName());
}
}

public static void main(String[] args) {
final Friend alphonse = new Friend("Alphonse");
final Friend gaston = new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
显然在调用bow时,由于又调用到了bowBack,每个线程都会锁死的。因为方法给的synchronized是只有在
方法调用完成时才会解锁, 而上面的代码是在一个锁上上后,再调用一个等开锁的方法,等新方法获得锁
然后再释放锁,才能再回到bow方法再释放锁,这就是逻辑锁死。
这种代码只有在走码或是设计时避免。








阅读(506) | 评论(0) | 转发(0) |
0

上一篇:CPI是什么

下一篇:JAVA线程

给主人留下些什么吧!~~