关于线程同步:synchronized

public synchronized void testfunc() {

   ...

}

 

synchronized在这里指执行这段函数代码时锁定当前对象。

还可以这样写:

public void testfunc() {

  synchronized(this) {

     ...

  }

}

两种写法意义相同。

 

接下来给出一个死锁的例子:

public class TestDeadLock implements Runnable { public int flag = 1; static Object o1 = new Object(),o2 = new Object(); public void run() { System.out.println("flag"+flag); if(flag == 1) { synchronized(o1) { try { Thread.sleep(500); } catch( Exception e) { e.printStackTrace(); } synchronized(o2) { System.out.println("1"); } } } if(flag == 0) { synchronized(o2) { try { Thread.sleep(500); } catch( Exception e) { e.printStackTrace(); } synchronized(o1) { System.out.println("1"); } } } } public static void main(String[] args) { TestDeadLock td1 = new TestDeadLock(); TestDeadLock td1 = new TestDeadLock(); td1.flag = 1; td2.flag = 0; Thread t1 = new Thread(td1); Thread t2 = new Thread(td2); t1.start(); t2.start(); } }

 

另外,再看另外一个例子:

public class TT implements Runnable{ int b = 100; public synchronized void m1() throws Exception{ b = 1000; Thread.sleep(5000); System.out.println("b="+b); } public void m2() { System.out.println(b); } public void run() { try { m1(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { TT tt = new TT(); Thread t = new Thread(tt); t.start(); Thread.sleep(1000); tt.m2(); } }

通过运行这个例子可以看出,在锁定了m1()方法时,其他线程依然可以访问未被锁定的方法。synchronized所起的作用只是保证同一时间只能有一个线程访问m1()方法而已。

 

当我们为m2加上sychronized:

public class TT implements Runnable{ int b = 100; public synchronized void m1() throws Exception{ b = 1000; Thread.sleep(5000); System.out.println("b="+b); } public synchronized void m2() { Thread.sleep(2500); b = 2000; } public void run() { try { m1(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { TT tt = new TT(); Thread t = new Thread(tt); t.start(); tt.m2(); System.out.println(tt.b); } }

打印出来结果是:

1000

b=1000

 

这个程序的执行过程是,首先执行m2()。锁定当前对象,因此必须等到m2()执行完了,锁释放了才能够执行m1()。在m2()中将b设为2000,然后执行m1()中的b=1000;然后线程睡眠,执行System.out.println(tt.b);然后线程继续执行System.out.println("b="+b);

因此最后打印结果是:

1000

b=1000;

 

最后给出一个生产者与消费者的模型:

public class ProducerConsumer { public static void main(String[] args) { SyncStack ss = new SyncStack(); Producer p = new Producer(ss); Consumer c = new Consumer(ss); new Thread(p).start(); new Thread(c).start(); } } class Bread { int id; Bread(int id) { this.id = id; } public String toString() { return "Bread:"+id; } } class SyncStack { int index = 0; Bread[] arrBd = new Bread[6]; public synchronized void push(Bread bd) { while(index == arrBd.lenght) { this.wait(); //当前对象访问的线程wait,并且锁自动释放开 //不同于sleep,sleep时锁依然锁定,并不会释放 } this.notify(); //叫醒在当前对象wait的线程 arrBd[index] = bd; index++; } public synchronized Bread pop() { while(index == 0) { this.wait(); } this.notify(); index--; return arrBd[index]; } } class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0;i<20;++i) { Bread bd = new Bread(i); ss.push(bd); } } } class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0;i<20;++i) { Bread bd = ss.pop(); System.out.println(bd); } } }

 

你可能感兴趣的:(thread,c,exception,object,String,Class)