java中實作同步的兩種方式:syschronized和lock的差別和聯系
java中同步與異步
/*
* 需求:
* 銀行有一個金庫
* 有兩個儲戶,分别存300元。每次存100 , 存三次
*
* 這個是有線程問題的,
*
* 我們應該通過下邊的三個方法來查找問題
* 1.明确哪些代碼是多線程運作的代碼
* 2.明确共享資料
* 3.明确多線程運作代碼中哪些是操作共享資料的
*/
class Bank
{
private int sum;
public synchronized void add (int n)
{
sum = sum + n;
try {Thread.sleep (10);}catch (Exception e){}
System.out.println ("sum="+ sum);
}
}
class Cus implements Runnable
{
private Bank bank = new Bank ();
public void run(){
for (int x=0; x<3;x++){
bank.add(100);
}
}
}
public class BankDemo {
public static void main(String[] args) {
Cus cus = new Cus ();
Thread t1 = new Thread (cus);
Thread t2 = new Thread (cus);
t1.start();
t2.start();
}
}
上邊代碼中的synchorinized 關鍵字 是可以放到函數前邊的,這就叫做同步函數 跟下邊的用法是一個作用
Object obj = new Object ();
Synchronized (obj) {
//需要同步的代碼塊
}
上邊的代碼的例子中的鎖使用的對象其實就是自己本身this,在多線程操作中為了讓線程安全,必須使用同一把鎖
如果同步函數被static 修飾,那麼就不是this了 因為靜态方法中沒有this 方法
靜态進記憶體是,記憶體中沒有本類對象,但是一定有該類對應的位元組碼檔案對象,叫做類名.class 該對象的類型是Class
靜态的同步方法是 使用的鎖是該方法坐在類的位元組碼檔案對象。類名.class
l例如
class Ticket implements Runnable
{
private static int tick = 100;
boolean flag = true;
Object obj = new Object();
public void run (){
if (flag){
while (true){
synchronized(Ticket.class){
if (tick > 0){
try {
Thread.sleep (10);
}
catch (Exception a)
{
}
System.out.println(Thread.currentThread().getName()+"sale:"+tick--);
}
}
}
}else
while (true)
show();
}
public static synchronized void show()
{
if (tick > 0){
try {
Thread.sleep (10);
}
catch (Exception a)
{
}
System.out.println(Thread.currentThread().getName()+"sale:"+tick--);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Ticket t = new Ticket ();
Thread t1 = new Thread (t);
Thread t2 = new Thread (t);
// Thread t3 = new Thread (t);
// Thread t4 = new Thread (t);
t1.start();
t2.start();
// t3.start();
// t4.start();
}
}