如何根据Scanner提供的条件让线程执行操作?

时间:2016-11-29 15:29:57

标签: java multithreading concurrency java.util.scanner java-threads

非常感谢你看看我的问题,我对一个可能有一个简单解决方案的问题非常困惑和沮丧,我真的很感激任何帮助。

我想要的只是关闭或打开屏障的两个实例,我想确定是否应该打开屏障的方式是通过扫描仪,所以如果我点击1,我应该收到消息"入口障碍" + threadid +"打开"

  public class MainClass{
    public static void main(String[] args) {

      EntranceBarrier e1 = new EntranceBarrier(); //Entrance Barrier 1
      EntranceBarrier e2 = new EntranceBarrier(); //Entrance Barrier 2

        e1.start();
        e2.start();

        System.out.println("Open?");
        Scanner sc = new Scanner(System.in);
        int operation = sc.nextInt();


       while(operation != 0){

          switch (operation) {
              case 1:
                  e1.setOpen(true);
                  e2.setOpen(true);
                  System.out.println("Opt. 1 Working");
                  break;
              case 2:
                  e1.setOpen(false);
                  e2.setOpen(false);
                  System.out.println("Opt. 2 Working");
                  break;
              default:
                  System.out.println("NOPE");
                  break;
          }

         System.out.println("Open?");
         operation = sc.nextInt();
       }


    }
   }

每当我运行主要方法时,它首先打印出"入口障碍关闭"当我向扫描仪输入1时,它只打印出"选项。 1工作"这意味着它没有将setOpen()更改为true。

这里是EntranceBarrier课程:

import java.io.*;
import java.util.Scanner;

public class EntranceBarrier extends Thread {

    private volatile boolean open = false;

    public synchronized void OpenBarrier(){
     if(isOpen()){
        try{
          String threadid = Thread.currentThread().getName();
          System.out.println("Entrance Barrier " + threadid + " Opened");
          Thread.sleep(5000);
        }catch(InterruptedException e){
           e.printStackTrace();
        }
       } else{
          System.out.println("Entrance Barrier Closed");

       }

    }

    public void run() {
       OpenBarrier();
    }

    public boolean isOpen() {
        return open;
    }

    public void setOpen(boolean open) {
        this.open = open;
    }

}

我不知道这个问题是否足够清楚,我真的希望你能帮助我,它正在撕毁我D:

1 个答案:

答案 0 :(得分:0)

我想提出一些改变。

首先,我想命名所有入口线程:

import java.util.Scanner;

public class MainClass {
public static void main(String[] args) {

    EntranceBarrier e1 = new EntranceBarrier(); // Entrance Barrier 1
    e1.setName("Bar1");
    EntranceBarrier e2 = new EntranceBarrier(); // Entrance Barrier 2
    e2.setName("Bar2");

    e1.start();
    e2.start();

    System.out.println("Open?");
    Scanner sc = new Scanner(System.in);
    int operation = sc.nextInt();

    while (operation != 0) {
        switch (operation) {
        case 1:
            e1.setOpen(true);
            e2.setOpen(true);
            System.out.println("Opt. 1 Working");
            break;
        case 2:
            e1.setOpen(false);
            e2.setOpen(false);
            System.out.println("Opt. 2 Working");
            break;
        default:
            System.out.println("NOPE");
            break;
        }

        System.out.println("Open?");
        operation = sc.nextInt();
    }
}
}

接下来,我想添加一个循环来进行主动检查,如果请求更改入口线程的状态,并且可以保存此信息的变量。

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

public class EntranceBarrier extends Thread {

    private volatile boolean open = false;
    private volatile boolean requestedState = false;

    private Lock lock = new ReentrantLock();

    public void OpenBarrier() {
        try {
            lock.lock();
            printState();
            lock.unlock();

            while (true) {
                lock.lock();
                if (requestedState != open) {
                    printState();

                    Thread.sleep(5000);
                    open = requestedState;

                    printState();
                }
                lock.unlock();
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            lock.unlock();
        }
    }

    private void printState() {
        if (requestedState == open) {
            if (open)
                System.out.println("Entrance Barrier " + getName() + " Opened");
            else
                System.out.println("Entrance Barrier " + getName() + " Closed");
        } else {
            if (requestedState)
                System.out.println("Entrance Barrier " + getName() + " Opening");
            else
                System.out.println("Entrance Barrier " + getName() + " Closing");
        }
    }

    public void run() {
        OpenBarrier();
    }

    public boolean isOpen() {
        return open;
    }

    public void setOpen(boolean open) {
        if (lock.tryLock()) {
            this.requestedState = open;
            lock.unlock();
        } else {
            System.out.println("Entrance Barrier " + getName() + " is moving");
        }
    }
}

我使用了reentrant lock而不是synchronized关键字,以便在锁已被锁定时进行检查。如果正在改变入口状态,它会使setOpen函数退出。

可以使用wait()/ notify()进一步升级EntranceBarrier。可以用更有效的方式替换主动等待。

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

public class EntranceBarrier extends Thread {

    private volatile boolean open = false;
    private volatile boolean requestedState = false;

    private Lock lock = new ReentrantLock();

    public void OpenBarrier() {
        try {
            lock.lock();
            printState();
            lock.unlock();

            while (true) {
                // waiting for state change request
                synchronized (this) {
                    wait();
                }
                lock.lock();
                if (requestedState != open) {
                    printState();

                    Thread.sleep(5000);
                    open = requestedState;

                    printState();
                }
                lock.unlock();
                // Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            lock.unlock();
        }
    }

    private void printState() {
        if (requestedState == open) {
            if (open)
                System.out.println("Entrance Barrier " + getName() + " Opened");
            else
                System.out.println("Entrance Barrier " + getName() + " Closed");
        } else {
            if (requestedState)
                System.out.println("Entrance Barrier " + getName() + " Opening");
            else
                System.out.println("Entrance Barrier " + getName() + " Closing");
        }
    }

    public void run() {
        OpenBarrier();
    }

    public boolean isOpen() {
        return open;
    }

    public void setOpen(boolean open) {
        if (lock.tryLock()) {
            this.requestedState = open;
            // notifying that state change was requested
            synchronized (this) {
                notify();
            }
            lock.unlock();
        } else {
            System.out.println("Entrance Barrier " + getName() + " is moving");
        }
    }
}