• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

线程间通信

znqdakn0k2f3871.png

对于两个线程A、B;

第一个线程a:

(1)判断:如果变量值为0

(2)工作:变量值1

(3)通知:A线程将变量-1通知B线程

第二个线程b:

(1)判断:如果变量值为1

(2)工作:变量值-1

(3)通知:线程B将变量1通知给线程A

诸如此类。

代码实现:方式一:synchronized关键字

包JUC.sync

//第一步是创建一个资源类,定义它的属性和操作方法。

类别共享{

//初始值

private int number=0;

//1方法

公共同步void incr()引发InterruptedException {

//第二步,判断工作通知。

如果(数字!=0) {//判断数值是否为0,如果不是,等待

this . wait();

}

//如果数值为0,则对1进行操作

号码;

system . out . println(thread . current thread()。getName() ' : '号);

//通知其他线程

this . notifyall();

}

//-1方法

公共同步void decr()引发InterruptedException {

//第二步,判断工作通知。

如果(数字!=1) {//判断数值是否为1,如果不是,等待

this . wait();

}

//如果数值为1,则运算-1

数字-;

system . out . println(thread . current thread()。getName() ' : '号);

//通知其他线程

this . notifyall();

}

}

公共类ThreadDemo1 {

//第三步,创建多线程,调用资源类的操作方法。

公共静态void main(String[] args) {

Share share=新份额();

//创建一个线程

新线程(()-{

for(int I=0;i 10i ) {

尝试{

share . incr();//1

} catch (InterruptedException e) {

e . printstacktrace();

}

}

},' AA ')。start();

新线程(()-{

for(int I=0;i 10i ) {

尝试{

share . decr();//-1

} catch (InterruptedException e) {

e . printstacktrace();

}

}

},' BB ')。start();

}

}

如果线程为4个,会出现 虚假唤醒 的问题

nmyhq3agrb33872.png

解决方案:

语句从if更改为while。而条件无论什么时候等待者睡觉或醒来,都必须被判断。

代码实现:方式二:Lock接口

包JUC.lock

mport java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //第一步 创建资源类,定义属性和操作方法 class Share { private int number = 0; //创建Lock final Lock lock = new ReentrantLock(); final Condition condition = lock.newCondition(); //+1 public void incr() throws InterruptedException { //上锁 lock.lock(); try{ //判断 while(number != 0){ condition.await(); } //干活 number++; System.out.println(Thread.currentThread().getName()+" :: "+number); //通知 condition.signalAll(); } finally { //解锁 lock.unlock(); } } //-1 public void decr() throws InterruptedException { //上锁 lock.lock(); try{ //判断 while(number != 1){ condition.await(); } //干活 number--; System.out.println(Thread.currentThread().getName()+" :: "+number); //通知 condition.signalAll(); } finally { //解锁 lock.unlock(); } } } public class ThreadDemo2 { public static void main(String[] args) { Share share = new Share(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { share.incr(); } catch (InterruptedException e) { e.printStackTrace(); } } },"AA").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { share.decr(); } catch (InterruptedException e) { e.printStackTrace(); } } },"BB").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { share.incr(); } catch (InterruptedException e) { e.printStackTrace(); } } },"CC").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { try { share.decr(); } catch (InterruptedException e) { e.printStackTrace(); } } },"DD").start(); } }

 

 

 

线程定制化通信

ceicxefy41z3873.png

 

方案:给每个线程定义一个标志位。

package JUC.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//第一步 创建资源类,定义属性和操作方法
class ShareResource {
    //定义标志位
    private int flag = 1;// 1 AA 2 BB 3 CC
    //创建Lock锁
    final Lock lock = new ReentrantLock();
    //创建三个condition
    final Condition c1  = lock.newCondition();
    final Condition c2  = lock.newCondition();
    final Condition c3  = lock.newCondition();
    //打印5次,参数第几轮
    public void print5(int loop) throws InterruptedException {
        //上锁
        lock.lock();
        try{
            //判断
            while(flag != 1){
                c1.await();
            }
            //干活
            for (int i = 1; i <= 5; i++) {
                System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数: "+loop);
            }
            //修改标志位
            flag = 2;
            //通知
            c2.signalAll();
        } finally {
            //解锁
            lock.unlock();
        }
    }
    //打印10次,参数第几轮
    public void print10(int loop) throws InterruptedException {
        //上锁
        lock.lock();
        try{
            //判断
            while(flag != 2){
                c2.await();
            }
            //干活
            for (int i = 1; i <= 10; i++) {
                System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数: "+loop);
            }
            //修改标志位
            flag = 3;
            //通知
            c3.signalAll();
        } finally {
            //解锁
            lock.unlock();
        }
    }
    //打印15次,参数第几轮
    public void print15(int loop) throws InterruptedException {
        //上锁
        lock.lock();
        try{
            //判断
            while(flag != 3){
                c3.await();
            }
            //干活
            for (int i = 1; i <= 15; i++) {
                System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数: "+loop);
            }
            //修改标志位
            flag = 1;
            //通知
            c1.signalAll();
        } finally {
            //解锁
            lock.unlock();
        }
    }
}
public class ThreadDemo3 {
    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    shareResource.print5(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    shareResource.print10(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    shareResource.print15(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"CC").start();
    }
}

 

Link to comment
Share on other sites