java线程同步与通信

来源:互联网 发布:python网络数据采集pdf 编辑:程序博客网 时间:2024/05/16 16:24

一、java线程同步:同一时间只能有一个线程访问共享资源。

1、原理:每个Java对象中都有一个监视程序,同一时间只有一个线程持有该监视程序。

2、同步的弊端:同步会让整个程序执行缓慢。

3、实现同步的方式:

1)同步方法:使用synchronized修饰需要同步的方法,同步整个方法,实现线程排队执行,用法参考代码:

public class SynchronizeMethodDemo implements Runnable {private static int money = 0;// 模拟共享资源public static void main(String[] args) {SynchronizeMethodDemo sm = new SynchronizeMethodDemo();Thread t1 = new Thread(sm, "线程A");Thread t2 = new Thread(sm, "线程B");t1.start();t2.start();}@Override<span style="color:#FF0000;">public synchronized void run</span>() {try {for (int i = 0; i < 2; i++) {System.out.println("当前线程:" + Thread.currentThread().getName()+ ":" + money++);Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}}}
运行结果:

当前线程:线程B:0当前线程:线程B:1当前线程:线程A:2当前线程:线程A:3
特殊情况:当2个线程使用的不是同一个对象,则这2个线程不能实现同步,代码如下:

public class SynchronizeMethodDemo implements Runnable {private static int money = 0;// 模拟共享资源public static void main(String[] args) {//sm和sm1不是同一个对象,各自有自己的监视程序,所以不能同步SynchronizeMethodDemo sm = new SynchronizeMethodDemo();SynchronizeMethodDemo sm1 = new SynchronizeMethodDemo();Thread t1 = new Thread(sm, "线程A");Thread t2 = new Thread(sm1, "线程B");t1.start();t2.start();}@Overridepublic synchronized void run() {try {for (int i = 0; i < 2; i++) {System.out.println("当前线程:" + Thread.currentThread().getName()+ ":" + money++);Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}}}
运行结果:

当前线程:线程B:0当前线程:线程A:1当前线程:线程B:2当前线程:线程A:3

2)同步语句块:使用synchronized修饰需要同步的代码,只同步方法里面的部分代码,使用参考代码(包含2种写法):

public class SynchronizeStatement implements Runnable {private static int money = 0;// 模拟共享资源<span style="color:#FF0000;">private Object obj=new Object();</span>public static void main(String[] args) {SynchronizeStatement sm = new SynchronizeStatement();Thread t1 = new Thread(sm, "线程A");Thread t2 = new Thread(sm, "线程B");t1.start();t2.start();}@Overridepublic void run() {<span style="color:#FF0000;">synchronized (this)</span> {for (int i = 0; i < 2; i++) {System.out.println("同步语句块1:" + Thread.currentThread().getName()+ ":" + money++);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}<span style="color:#FF0000;">synchronized (obj)</span> {for (int i = 0; i < 2; i++) {System.out.println("同步语句块2:" + Thread.currentThread().getName()+ ":" + money++);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}}
二、实现线程间的通信

1、线程间通信使用的方法:

1)wait()方法:告知当前线程放弃对监视程序的控制并等待直至另一线程调用notify()方法。

2)notify()方法:唤醒正在等待被执行对象的监视程序的线程。如果多个线程正在等待中,将随机选择其中一个线程。

3)notifyAll()方法:唤醒正在等待对象的监视程序的所有线程。

2、使用参考代码:

class Synchronize {int d;boolean flag = false;// 表示是否已生产产品//消费商品synchronized int getData() {if (!flag) {try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println("Get Data:" + d);flag = false;notify();//通知生产者,生产新的商品return d;}// 生产商品synchronized void putData(int d) {// 如果已经生产产品,等待if (flag) {try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}this.d = d;flag = true;//通知消费者消费商品System.out.println("put Data:" + d);notify();}}// 生产者线程class Producer extends Thread {Synchronize t;public Producer(Synchronize t) {this.t = t;}public void run() {int data = 700;while (true) {System.out.println("put");t.putData(data++);}}}class Consumer extends Thread {Synchronize t;public Consumer(Synchronize t) {this.t = t;}public void run() {while (true) {System.out.println("get");t.getData();}}}public class ProducerConsumer {public static void main(String[] args) {Synchronize obj = new Synchronize();Producer t1 = new Producer(obj);Consumer t2 = new Consumer(obj);t1.start();t2.start();}}


0 0
原创粉丝点击