java线程同步与通信
2016-08-02 20:00
483 查看
一、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();
}
@Override
public 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();
}
@Override
public 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 block
e.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 block
e.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();
}
}
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();
}
@Override
public 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();
}
@Override
public 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 block
e.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 block
e.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();
}
}
相关文章推荐
- java同步和互斥 : 线程之间通信
- Java线程同步和线程间通信代码和控制线程关闭
- Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信
- java基础——多线程(线程的同步互斥与通信)
- java 多个线程之间同步通信
- java基础——多线程(线程的同步互斥与通信)
- java多线程(三) 线程的同步与通信
- java多线程之线程间同步通信
- JAVA线程同步、通信、中断
- Java同步Socket通信例子(线程方式) ,完整版
- Java并发——线程间通信与同步技术
- Java复习-线程之间的通信与同步
- Java 线程通信的安全问题(同步)
- Java线程间通信的同步问题、wait/notify使用
- java多线程学习-同步之线程通信
- Android(java)学习笔记70:同步中的死锁问题以及线程通信问题
- java线程同步及通信Demo——传统的线程通信
- 【java】同步,线程通信,lock
- Java线程同步与线程通信常用方法
- java线程间的同步与通信