Как можно удостовериться в Java, что блок кода не может быть прерван никаким другим потоком

Вы можете добиться этого, изменив идентификатор checkbox на класс (идентификаторы должны быть уникальными). При связывании события click с javascript вы получаете хорошее использование this. Вы можете использовать свойство property this.nextElementSibling, чтобы получить .checkbox, принадлежащий стрелке.

Также был изменен оператор if для проверки свойства display элемента вместо глобального var. Вам нужно установить начальное значение на none, чтобы избежать ошибок (это не совсем то же самое, что стиль css)

Также вы можете комбинировать две функции в зависимости от их использования. [1115 ]

Примечание: Вы должны также изменить элементы с идентификатором arrow, чтобы я был уникальным. С этим фрагментом проблем не возникло, но, скорее всего, в будущем у вас начнутся головные боли.

document.querySelectorAll(".selectBox").forEach((el) => {
  el.addEventListener('click', showCheckboxes);
  el.addEventListener('click', changeArrow);
  el.nextElementSibling.style.display = "none";
});


function showCheckboxes() {
  var thisCheckbox = this.nextElementSibling;
  if (thisCheckbox.style.display == "none") {
    thisCheckbox.style.display = "block";
  } else {
    thisCheckbox.style.display = "none";
  }
}

function changeArrow() {
  var arrow = this.getElementsByClassName('arrow')[0];
  
  if (arrow.classList.contains("down-arrow")) {
    arrow.classList.remove("down-arrow");
    arrow.classList.add("up-arrow");
  } else if (arrow.classList.contains("up-arrow")) {
    arrow.classList.remove("up-arrow");
    arrow.classList.add("down-arrow");
  }
}
.github {
  margin-top: 50px;
}

.multiselect {
  width: 170px;
  margin-top: 80px;
  position: absolute;
  z-index: 40;
  display: flex;
  flex-direction: row;
}

.selectBox {
  position: relative;
}

.selectBox select {
  width: 100%;
  font-weight: bold;
}

.overSelect {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}

.checkboxes {
  background-color: #e5e5e5;
  border: none;
}

.checkboxes__container {
  display: flex;
  height: auto;
  margin-bottom: 10px;
}

.checkboxes__container--input {
  display: flex;
  margin: 0 15px;
}

.checkboxes__container--text {
  display: flex;
  align-items: center;
  margin: 0 15px;
}

.checkboxes input {
  border: none;
  background-color: #fff;
}

.checkboxes label {
  display: block;
  width: 25px;
  height: 25px;
  cursor: pointer;
  position: relative;
  background-color: #fff;
  border: 1px solid lightgray;
}

.checkboxes label:after {
  content: '';
  width: 13px;
  height: 11px;
  position: absolute;
  top: 4px;
  left: 4px;
  border: 2px solid #6d3838;
  border-top: none;
  border-right: none;
  background: transparent;
  opacity: 0;
  -webkit-transform: rotate(-45deg);
  transform: rotate(-45deg);
}

.checkboxes label:hover::after {
  opacity: 0;
}

.checkboxes input[type=checkbox] {
  visibility: hidden;
}

.checkboxes input[type=checkbox]:checked+label:after {
  opacity: 1;
}

select {
  -webkit-appearance: none;
  -moz-appearance: none;
  text-indent: 1px;
  text-overflow: '';
  background-color: transparent;
  width: 170px !important;
  height: 35px;
  border: none;
  box-sizing: border-box;
  padding-left: 25px;
}

.select-container {
  display: flex;
  width: 170px;
  background-color: #e5e5e5;
}

.down-arrow {
  background-image: url("https://cdn3.iconfinder.com/data/icons/fatcow/32/cursor.png");
}

.up-arrow {
  background-image: url("https://cdn0.iconfinder.com/data/icons/fatcow/32/change_password.png");
}

.arrow {
  width: 35px;
  box-sizing: border-box;
  padding: 10px;
  background-color: #00a671;
}

.squaredFour {
  width: 20px;
  position: relative;
  margin: 20px auto;
}

.squaredFour label {
  width: 25px;
  height: 25px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
  background-color: #fff;
  border: 1px solid lightgray;
}

.squaredFour label:after {
  content: '';
  width: 12px;
  height: 8px;
  position: absolute;
  top: 20%;
  left: 25%;
  /* transform: translate(-50%,-50%); */
  border: 2px solid #6d3838;
  border-top: none;
  border-right: none;
  background: transparent;
  opacity: 0;
  -webkit-transform: rotate(-45deg);
  transform: rotate(-45deg);
}

.squaredFour label:hover::after {
  opacity: 0;
}

.squaredFour input[type=checkbox] {
  visibility: hidden;
}

.squaredFour input[type=checkbox]:checked+label:after {
  opacity: 1;
}
<div class="multiselect">
  <div>
    <div class="selectBox">
      <div class="select-container">
        <select>
          <option>ogródek/strych</option>
        </select>
        <img class="arrow down-arrow" alt="">
      </div>

      <div class="overSelect"></div>
    </div>

    <div class="checkboxes">
      <div class="checkboxes__container">
        <span class="checkboxes__container--input">
					<input type="checkbox" id="one">
					<label for="one"></label>
				</span>
        <span class="checkboxes__container--text">
					<span>ogródek</span>
        </span>
      </div>
      <div class="checkboxes__container">
        <span class="checkboxes__container--input">
					<input type="checkbox" id="two">
					<label for="two"></label>
				</span>
        <span class="checkboxes__container--text">
					<span>strych</span>
        </span>
      </div>

    </div>
  </div>
  <div>
    <div class="selectBox">
      <div class="select-container">
        <select>
          <option>status</option>
        </select>
        <img class="arrow down-arrow" alt="">
      </div>

      <div class="overSelect"></div>
    </div>

    <div class="checkboxes">
      <div class="checkboxes__container">
        <span class="checkboxes__container--input">
					<input type="checkbox" id="three">
					<label for="three"></label>
				</span>
        <span class="checkboxes__container--text">
					<span>wolne</span>
        </span>
      </div>
      <div class="checkboxes__container">
        <span class="checkboxes__container--input">
					<input type="checkbox" id="four">
					<label for="four"></label>
				</span>
        <span class="checkboxes__container--text">
					<span>rezerwacja</span>
        </span>
      </div>

    </div>
  </div>
  <div>
    <div class="selectBox">
      <div class="select-container">
        <select>
          <option>status</option>
        </select>
        <img class="arrow down-arrow" alt="">
      </div>

      <div class="overSelect"></div>
    </div>

    <div class="checkboxes">
      <div class="checkboxes__container">
        <span class="checkboxes__container--input">
					<input type="checkbox" id="three">
					<label for="three"></label>
				</span>
        <span class="checkboxes__container--text">
					<span>wolne</span>
        </span>
      </div>
      <div class="checkboxes__container">
        <span class="checkboxes__container--input">
					<input type="checkbox" id="four">
					<label for="four"></label>
				</span>
        <span class="checkboxes__container--text">
					<span>rezerwacja</span>
        </span>
      </div>

    </div>
  </div>

</div>

11
задан Mat 17 May 2012 в 20:54
поделиться

7 ответов

Вы не можете - по крайней мере, не с нормальным Java, работая на нормальной, неоперационной системе реального времени. Даже если другие потоки не прерывают Ваш, другие процессы могли бы хорошо сделать так. В основном Вы не сможете гарантировать, что Вы получаете ЦП все себе, пока Вы не сделаны. Если Вы хотите этот вид гарантии, необходимо использовать что-то как Система реального времени Java. Я не знаю достаточно об этом, чтобы знать, предоставило ли это определенно услугу, которую Вы хотите все же.

Лучшая вещь сделать, избегают того требования во-первых.

14
ответ дан 3 December 2019 в 02:41
поделиться

На самом деле можно сделать это при управлении экземпляром потока, Вы работаете. Очевидно, существует тонна протестов на этом (как зависание io операции), но по существу можно разделить Поток на подклассы и переопределить прерывание () метод. можно затем поместить своего рода булевскую переменную, на месте таким образом, что при зеркальном отражении флага прерывание () обращается потоку, или проигнорированы или еще лучше на потом сохранены.

3
ответ дан 3 December 2019 в 02:41
поделиться

Действительно необходимо оставить больше информации.

Вы не можете мешать другим системным процессам выполниться, если Вы не работаете на ОС в реальном времени. Это то, что Вы имеете в виду?

Вы не можете остановить сборку "мусора", и т.д. если Вы не выполняете Java в реальном времени. Это то, что Вы хотели?

Единственная оставленная вещь: Если Вы просто хотите, чтобы все ВАШИ другие потоки Java не прервали друг друга, потому что они все имеют тенденцию получать доступ к некоторому ресурсу волей-неволей свободно, Вы делаете его неправильно. Разработайте его правильно так, чтобы объекты/данные, к которым НУЖНО получить доступ синхронизируемым способом, синхронизировались, затем не волнуются о других потоках, прерывающих Вас, потому что Ваши синхронизируемые объекты безопасны.

Я пропускал какие-либо возможные случаи?

3
ответ дан 3 December 2019 в 02:41
поделиться

Принятие, которое Вы только обеспокоены прикладным уровнем, распараллеливает конкуренцию и предположение, что Вы готовы носиться с блокировками, как предложили другие (который, по моему скромному мнению, является действительно плохой идеей), затем необходимо использовать a ReadWriteLock и не синхронизация простого объекта:

import java.java.util.concurrent.locks.*;

// create a fair read/write lock
final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);

// the main thread grabs the write lock to exclude other threads
final Lock writeLock = rwLock.writeLock();

// All other threads hold the read lock whenever they do 
// *anything* to make sure the writer is exclusive when 
// it is running. NOTE: the other threads must also 
// occasionally *drop* the lock so the writer has a chance 
// to run!
final Lock readLock = rwLock.readLock();

new Thread(new Runnable() {
  public void run() {
    while(condition) {

      writeLock.lock();
      try {
        *code that must not be interrupted*
      } finally {
        writeLock.unlock();
      }

      *some more code*
    }
  }
}).start();

new SomeOtherThread(readLock).start();
new YetAntherThread(readLock).start();
3
ответ дан 3 December 2019 в 02:41
поделиться

Используя синхронизируемый подход (в различных формах, отправленных здесь), не помогает вообще.

Тот подход только помогает удостовериться, что один поток выполняет критический раздел за один раз, но это не то, что Вы хотите. Вы должны, чтобы препятствовать тому, чтобы поток был прерван.

Блокировка чтения-записи, кажется, помогает, но не имеет никакого значения, так как никакой другой поток не пытается использовать блокировку записи.

Это только подает заявку немного медленнее, потому что JVM должна выполнить дополнительные проверки для выполнения синхронизируемого раздела (используемый только одним потоком, таким образом трата ЦП)

На самом деле в пути у Вас есть он, поток "действительно" не прерывается. Но кажется, что это делает, потому что это должно привести к процессорному времени другим потокам. Путем работы потоков; ЦП дает каждому потоку шанс работать на некоторое время в течение очень промежутков времени коротких замыканий. Даже тот, когда единственное выполнение потока, тот поток приводит к процессорному времени с другими потоками других приложений (Предполагающий, что единственная машина процессора сохраняет обсуждение простым).

Это - вероятно, причина, которой это кажется Вам как поток, приостанавливается/прерывается время от времени, потому что система позволяет каждому потоку в выполнении приложения на некоторое время.

Так, что можно сделать?

Для увеличения восприятия никаких прерываний одна вещь, которую можно сделать, присваивают более высокий приоритет потоку и уменьшают его для остальных.

Если все потоки имеют тот же приоритет, одно возможное расписание потоков 1,2,3 могло бы быть похожим на это:

равномерно распределенный

1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3

При установке макс. для 1, и минута для 2,3 это могло быть похожим на это:

Больше CPU для поточной обработки 1

1,1,1,2,1,1,3,1,1,1,2,1,1,1,3,1,2,1,1,1

Чтобы поток был прерван другим потоком, это должно быть в прерываемом состоянии, достигнутом путем вызова, Object.wait, Thread.join или Thread.sleep

Ниже некоторого забавного кода для экспериментирования.


Код 1: Тест, как изменить приоритет потоков. Посмотрите шаблоны на ouput.

public class Test {
    public static void main( String [] args ) throws InterruptedException {
        Thread one = new Thread(){
            public void run(){
                while ( true ) {
                    System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
                }
            }
        };
        Thread two = new Thread(){
            public void run(){
                while ( true ) {
                    System.out.println(".............................................");
                }
            }
        };
        Thread three = new Thread(){
            public void run(){
                while ( true ) {
                    System.out.println("------------------------------------------");
                }
            }
        };

        // Try uncommenting this one by one and see the difference.

        //one.setPriority( Thread.MAX_PRIORITY );
        //two.setPriority( Thread.MIN_PRIORITY );
        //three.setPriority( Thread.MIN_PRIORITY );
        one.start();
        two.start();
        three.start();

        // The code below makes no difference
        // because "one" is not interruptable
        Thread.sleep( 10000 ); // This is the "main" thread, letting the others thread run for aprox 10 secs.
        one.interrupt();  // Nice try though.
    }
}

Код 2. Образец того, как может быть поток на самом деле быть прерванным (при сне в этом случае)

public class X{
    public static void main( String [] args ) throws InterruptedException  {
        Thread a = new Thread(){ 

            public void run(){ 

                int i = 1 ; 
                while ( true ){ 
                    if ( i++ % 100 == 0 ) try {
                        System.out.println("Sleeping...");
                        Thread.sleep(500);
                    } catch ( InterruptedException ie ) {
                        System.out.println( "I was interrpted from my sleep. We all shall die!! " );
                        System.exit(0);
                    }
                    System.out.print("E,"); 
                }
            }

         };
        a.start();


        Thread.sleep( 3000 ); // Main thread letting run "a" for 3 secs. 
        a.interrupt(); // It will succeed only if the thread is in an interruptable state
    }
}
3
ответ дан 3 December 2019 в 02:41
поделиться

Прежде чем поток прерван, checkAccess менеджера безопасности (), метод называют. Реализуйте своего собственного менеджера безопасности, назовите System.setSecurityManager, чтобы установить его и удостовериться, что он не позволяет никакому другому потоку прервать Вас, в то время как это находится в критическом разделе.

2
ответ дан 3 December 2019 в 02:41
поделиться

Лучше всего промежуточное решение состояло бы в том, чтобы синхронизировать все потоки на некотором общем объекте так, чтобы никакие другие потоки не были выполнимы, в то время как Вы находитесь в критическом разделе.

Кроме этого я не думаю, что это возможно. И мне довольно любопытно относительно того, какая проблема, которая требует этого типа решения?

0
ответ дан 3 December 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: