java 线程入门(备忘)

[b][color=blue]零、一些概念[/color][/b]
[b]共享变量[/b]:一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。

[b]共享变量可见性[/b]:一个线程对共享变量值的修改,能够及时被其它线程看见。
实现的过程,线程1 将自己工作内存中的变量修改后,更新到主内存中,然后主内存将新值更新到线程2的工作内存中去。

[b]JMM[/b]:Java 内存模型(Java Memory Model)

[b]主内存[/b]:所有的变量都保存在主内存中。

[b]工作内存[/b]:每个线程都有自己独立的工作内存,保存了主内存中变量的一个copy (副本)

关系图如下:

[img]http://dl2.iteye.com/upload/attachment/0107/2825/026596b8-3019-3173-9714-d56818bb02bd.png[/img]


[b][color=blue]一、实现线程的两种方式[/color][/b]

Thd1.java

public class Thd1 extends Thread {//继承Thread类创建线程
private long waitTime;
public Thd1(long wt){
this.waitTime=wt;
}
public void run(){

try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1");
}
}
[/code]

Thd2.java

[code="java"]public class Thd2 implements Runnable {//实现Runnable接口来创建线程
private long waitTime;
public Thd2(long wt){
this.waitTime=wt;
}
public void run() {
System.out.println("thread2");
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


TestThd.java

public class TestThd {//测试类
/**
* @param args
*/
public static void main(String[] args) {
Thd1 t1=new Thd1(3000);//继承Thread 类并重写run()的线程;
t1.start();

Thd2 t2=new Thd2(3000);//实现Runable 接口 重写run()的线程
Thread t=new Thread(t2);
t.start();
/*小结:线程启动方式都为start()。所以
* 第二种实现一个线程时也要得到thread的一个实例。
* 因为只有它有start().
*本人拙见:如有错误请各位指正,谢谢!
* */
}
}



[b][color=blue]二、共享变量线程间可见性实现[/color][/b]
线程解锁前,必须要把共享变量的最新值刷新到主内存中去。
线程加锁时,将清空工作内存中共享变量的值。从而使用共享变量时,需要从主内存中重新加载共享变量的最新值。

线程解锁前对共享变量的修改,在下次加锁时对其它线程可见。

1、synchronized 实现可见性
①:获取互斥锁
②:清空工作内存
③:从主内存中copy 共享变量的最新副本到工作内存中。
④:执行代码
⑤:将更改后的共享变量的值刷新到主内存中。
⑥:释放互斥锁

public class Account { 
//共享变量
  String holderName;
  float amount;
/*构造方法*/
  public Account(String name, float amt) {
   holderName = name;
   amount = amt;
  }
/*存钱*/
  public synchronized void deposit(float amt) {
   amount += amt;
  }
/*取钱*/
  public synchronized void withdraw(float amt) {
   amount -= amt;
  }
/*查看金额*/
  public float checkBalance() {
   return amount;
  }
}


 deposit() 和 withdraw() 函数都需要这个锁来进行操作,所以当一个函数运行时,另一个函数就被阻塞。请注意, checkBalance() 未作更改,它严格来讲是一个读函数。因为 checkBalance() 未作同步处理,所以任何其他方法都不会阻塞它,它也不会阻塞任何其他方法,不管那些方法是否进行了同步处理。


2、volatile 实现可见性




3、synchronized 与 volatile 的比较
> volatile 不需要加锁,不会阻塞线程,比synchronized 轻量级,所以执行效率高一些。
> 从内存可见性角度来看,volatile 读相当于加锁,写相当于解锁。
> synchronized 可以保证原子性和可见性,volatile 只能保证可见性,不能保证原子性







不错的文章:[url=http://www.blogjava.net/Werther/archive/2009/07/21/287656.html]http://www.blogjava.net/Werther/archive/2009/07/21/287656.html[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值