多线程:切换上下文

时间:2016-02-05 14:13:51

标签: java java-threads

我写了一个小样本代码:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
    <system.webServer>
  </system.webServer>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
                          <httpRuntime targetFramework="4.0" requestValidationMode="2.0" maxRequestLength="65536000"/>
                          <pages validateRequest="false" />
    <httpModules>
          <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
    </httpModules>
  </system.web>
  <system.serviceModel>


    <bindings>
      <webHttpBinding>
        <binding maxReceivedMessageSize="65536000" transferMode="StreamedRequest">
          <security mode="None" />
        </binding>
      </webHttpBinding>
    </bindings>


    <behaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp defaultOutgoingResponseFormat="Json"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="webHttpBinding" scheme="http"/>
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="ApplicationInsightsWebTracking"/>
    </modules>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
    <validation validateIntegratedModeConfiguration="false"/>
  </system.webServer>

  <runtime>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>

        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>

        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0"/>

      </dependentAssembly>

    </assemblyBinding>

  </runtime>
</configuration>

当我像以下那样运行时:

public class Button2 implements Runnable{    
    JButton jButton = new JButton();
    static boolean changeContext = false;    
    public Button2(){
        jButton.setText("ButtonTWO");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                changeContext = true;
                ((JButton)e.getSource()).setEnabled(false);
            }
        });
    }
    @Override
    public void run() {
        System.out.println("ButtonTWO run...");
        jButton.setEnabled(true);
        while(true){
            if(changeContext)
                break;
        }
        changeContext = false;        
    }
}

即使单击按钮,它也永远不会出现。

如果我在Button2 threadTWO = new Button2(); Thread thread2; try{ thread2 = new Thread(threadTWO); thread2.start(); thread2.join(); }catch(Exception ex){ System.out.println("Ëxception caught"); } 之后添加sysoutThread.sleep(1),则会出现while循环。可能的原因是什么?

1 个答案:

答案 0 :(得分:0)

我假设你正在运行EDT的底部。因此,您正在创建按钮(并希望以某种方式将其添加到您的UI)然后启动线程并让EDT等待线程死(thread2.join()),因此EDT无法处理事件和{永远不会调用{1}}。

添加一些内容会导致循环结束可能是由于缺少大括号:

如果changeContext = true为真,这只会结​​束循环:

changeContext

我假设你这样做了:

if(changeContext)
   break;

如果if(changeContext) Thread.sleep(1); break; 为真,则上述调用会休眠,然后立即结束循环(changeContext不再位于if-block内。所以如果你想要一致的行为,请按以下方式编写:

break
顺便说一下,苹果去年有一个安全问题,它基本上有类似的来源(双if(changeContext) { Thread.sleep(1); break; } 而没有大括号)。