同步出现的原因是当线程中使用共享资源时候,为了资源的独占性。这样可以避免获得结果是不正确的。
如果,不是使用共享资源,不建议使用同步!因为这会使多线程变成单线程!而且处理不当,会引起死锁!
比如我们所写线程程序要的结果是:
Count value is: 1
Count value is: 2
Count value is: 3
Count value is: 4
1. 方法同步
没有方法同步的代码:
public class SynchDemo2 implements Runnable { StringBuffer buffer; int counter; public SynchDemo2() { // TODO Auto-generated constructor stub buffer = new StringBuffer(); counter = 1; } public void addMessage(String message) { int tempVariable = counter++; buffer.append(message + tempVariable + "/r/n"); } public void run() { // TODO Auto-generated method stub String message = "Count value is: "; try { Thread.sleep(500); } catch (InterruptedException iex) { // TODO: handle exception } addMessage(message); } /** * @param args */ public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub SynchDemo2 sd = new SynchDemo2(); Thread t1 = new Thread(sd); Thread t2 = new Thread(sd); Thread t3 = new Thread(sd); Thread t4 = new Thread(sd); t1.start(); t2.start(); t3.start(); t4.start(); t1.join(); t2.join(); t3.join(); t4.join(); System.out.println(sd.buffer); } }
但是,运行这个程序时,每次排列都是不同的!怎样才能得到我们想要的结果呢?
只需要同步方法addMessage(),即在前面加上“synchronized ”关键字!
有方法同步的代码:
public class SynchDemo2 implements Runnable { StringBuffer buffer; int counter; public SynchDemo2() { // TODO Auto-generated constructor stub buffer = new StringBuffer(); counter = 1; } public synchronized void addMessage(String message) { int tempVariable = counter++; buffer.append(message + tempVariable + "/r/n"); } public void run() { // TODO Auto-generated method stub String message = "Count value is: "; try { Thread.sleep(500); } catch (InterruptedException iex) { // TODO: handle exception } addMessage(message); } /** * @param args */ public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub SynchDemo2 sd = new SynchDemo2(); Thread t1 = new Thread(sd); Thread t2 = new Thread(sd); Thread t3 = new Thread(sd); Thread t4 = new Thread(sd); t1.start(); t2.start(); t3.start(); t4.start(); t1.join(); t2.join(); t3.join(); t4.join(); System.out.println(sd.buffer); } }
2. 块同步
没有块同步的代码:
public class SynchDemo implements Runnable { StringBuffer buffer; int counter; public SynchDemo() { // TODO Auto-generated constructor stub buffer = new StringBuffer(); counter = 1; } public void run() { // TODO Auto-generated method stub int tempVariable = counter++; String message = "Count value is: " + tempVariable + "/r/n"; try { Thread.sleep(500); } catch (InterruptedException iex) { // TODO: handle exception } buffer.append(message); } /** * @param args */ public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub SynchDemo sd = new SynchDemo(); Thread t1 = new Thread(sd); Thread t2 = new Thread(sd); Thread t3 = new Thread(sd); Thread t4 = new Thread(sd); t1.start(); t2.start(); t3.start(); t4.start(); t1.join(); t2.join(); t3.join(); t4.join(); System.out.println(sd.buffer); } }
但是,运行这个程序时,每次排列都是不同的!怎样才能得到我们想要的结果呢?
只需要把我们要同步的块前加“synchronized ”关键字!
代码如下:
public class SynchDemo implements Runnable { StringBuffer buffer; int counter; public SynchDemo() { // TODO Auto-generated constructor stub buffer = new StringBuffer(); counter = 1; } public void run() { // TODO Auto-generated method stub synchronized (buffer) { int tempVariable = counter++; String message = "Count value is: " + tempVariable + "/r/n"; try { Thread.sleep(500); } catch (InterruptedException iex) { // TODO: handle exception } buffer.append(message); } } /** * @param args */ public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub SynchDemo sd = new SynchDemo(); Thread t1 = new Thread(sd); Thread t2 = new Thread(sd); Thread t3 = new Thread(sd); Thread t4 = new Thread(sd); t1.start(); t2.start(); t3.start(); t4.start(); t1.join(); t2.join(); t3.join(); t4.join(); System.out.println(sd.buffer); } }