0
点赞
收藏
分享

微信扫一扫

信号量在多线程通讯运用

Resin_Wu 2022-08-04 阅读 97

同步的三个方法:

   必须在同步块 或者同步方法中使用

  1. notify()  停止访问当前线程,转去执行挂起的线程
  2. notifyALL()
  3. wait() 挂起 释放对线程资源的访问  如果有参数时间 那么再等待特定的时间再挂起

 

class CommonTalkVar{
private char product;
/**同步信号量
* true: 持有产品状态
* false: 已经消费产品状态
* */
private boolean isProduced=false;

/**
* @description production method
*/
public synchronized void putCommonData(char product){
if(isProduced){
try {
System.out.println(Thread.currentThread().getName()+"消费者还没有消费产品");
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
this.product=product;
this.isProduced=true;
System.out.println(Thread.currentThread().getName()+"生产者生产:"+this.product);
notify();
}
/**
* @description consumer method
*/
public synchronized char getCommonData(){
if(!isProduced){
try {
System.out.println(Thread.currentThread().getName()+"生产者还没有生产产品");
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
this.isProduced=false;
System.out.println(Thread.currentThread().getName()+"消费者消费:"+this.product);
notify();
return this.product;
}
}

class Consumer extends Thread{
private CommonTalkVar commonTalkVar;

public Consumer(CommonTalkVar commonTalkVar){
this.commonTalkVar=commonTalkVar;
}

@Override
public void run() {
char tempc;
do{
try {
Thread.sleep((int)(Math.random()*3000));
}catch (InterruptedException e){
e.printStackTrace();
}
tempc=commonTalkVar.getCommonData();
}while (tempc!='D');
}
}

class Product extends Thread{
private CommonTalkVar commonTalkVar;
public Product(CommonTalkVar commonTalkVar){
this.commonTalkVar=commonTalkVar;
}

@Override
public void run() {
for (char i = 'A'; i <= 'D'; i++){
try {
Thread.sleep((int)(Math.random()*3000));
}catch (InterruptedException e){
e.printStackTrace();
}
commonTalkVar.putCommonData(i);
}
}
}

public class ConsumerAndProduct {
public static void main(String[] args) {
CommonTalkVar talkVar = new CommonTalkVar();

new Consumer(talkVar).start();
new Product(talkVar).start();
}
}

多线程的的顺序控制

实际上就是注意 notifyALL() 方法的控制用法

package Thread;

public class Demo1_Synchronized {

/**
* @param args
* 同步代码块
*/
public static void main(String[] args) {
final Printer p = new Printer();

new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();

new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();

new Thread() {
public void run() {
while(true) {
try {
p.print3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

}

class Printer {
Demo d = new Demo();

private static volatile int signal=1;

public void print1() throws InterruptedException {
synchronized (this) {
while(this.signal!=1) {
this.wait();
}
this.signal=2;
System.out.println("11111");
this.notifyAll();
}
}

public void print2() throws InterruptedException {
synchronized (this) {
while(this.signal!=2) {
this.wait();
}
this.signal=3;
System.out.println("22222");
this.notifyAll();
}
}

public void print3() throws InterruptedException {
synchronized (this) {
while(this.signal!=3) {
this.wait();
}
this.signal=1;
System.out.println("33333");
this.notifyAll();
}
}
}

//定义的锁类
class Demo {
}

锁的同步

package Thread;

import java.util.concurrent.locks.ReentrantLock;

public class Test6 {

public static void main(String[] args) {
new Ticket12().start();
new Ticket12().start();
new Ticket12().start();
new Ticket12().start();
}

}
class Ticket12 extends Thread {
private static volatile int ticket = 100;

private static final ReentrantLock lock=new ReentrantLock();
public void run() {
while (true) {
lock.lock();
try {
if (ticket <= 0) {
break;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "这是第" + ticket-- + "号票");

} finally {
lock.unlock();
}
}
}
}

可重入锁的用法

package Thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Demo1_ReentrantLock {
public static void main(String[] args) {
final PrinterReentrantLock p = new PrinterReentrantLock();

new Thread() {
public void run() {
while(true) {
try {
p.print1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();

new Thread() {
public void run() {
while(true) {
try {
p.print2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();

new Thread() {
public void run() {
while(true) {
try {
p.print3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

}

class PrinterReentrantLock {

private int signal=1;

private static final ReentrantLock lock=new ReentrantLock();

private static final Condition c1=lock.newCondition();
private static final Condition c2=lock.newCondition();
private static final Condition c3=lock.newCondition();

public void print1() throws InterruptedException {
lock.lock();
try {
while (this.signal != 1) {
c1.await();
}
this.signal = 2;
System.out.println("11111");
c2.signal();
} finally {
lock.unlock();
}
}

public void print2() throws InterruptedException {
lock.lock();
try {
while (this.signal != 2) {
c2.await();
}
this.signal = 3;
System.out.println("22222");
c3.signal();
} finally {
lock.unlock();
}
}

public void print3() throws InterruptedException {
lock.lock();
try {
while (this.signal != 3) {
c3.await();
}
this.signal = 1;
System.out.println("33333");
c1.signal();
} finally {
lock.unlock();
}
}
}

 



举报

相关推荐

0 条评论