13がリリースされました。Oneが開催されていて、櫻庭も参加しています。SEの変更をまとめておきます。13も変更はかなり少ないです。提案されたJEPは5個。ライブラリに関するJEPはなく、言語使用に関するJEPが2つです。12でもPreview機能で入っていましたが、再検討されて新たにPreview機能として入っています。値を返す時のyieldが一番の違いです。Literalの再検討版です。テキストブロックもpreview機能なので、今後変更される可能性があります。本題のAPIの方です。こちらもそれほど変更は大きくありません。今回もABC順にならんでいます。同じように、セキュリティ系のAPIはちゃんと理解していないので、省略してます。13では2つのメソッドが廃止になっています。9で@DeprecatedのforRemovalがtrueになったメソッドです。今まで残していたのか不思議なくらいですねw廃止予定のAPI廃止予定APIの追加は多いです。パッケージjavax.security.certクラスjavax.security.cert.Certificatejavax.security.cert.X509Certificate例外javax.security.cert.CertificateEncodingExceptionjavax.security.cert.CertificateExceptionjavax.security.cert.CertificateExpiredExceptionjavax.security.cert.CertificateNotYetValidExceptionjavax.security.cert.CertificateParsingExceptionメソッドjava.lang.String.formattedjava.lang.String.stripIndentjava.lang.String.translateEscapesjavax.net.ssl.HandshakeCompletedEvent.getPeerCertificateChainjavax.net.ssl.SSLSession.getPeerCertificateChainjavax.security.certパッケージは、java.security.certパッケージを使うようにということです。13でforRemoval=trueになったということで、廃止することが決まったということです。13で追加されたメソッドです。13で追加されたのに、forRemoval=trueというのは、どういうこと?という感じですね。これらのメソッドの機能については後述しますが、いずれもテキストブロックに関連しているメソッドなのです。テキストブロックがpreviewから正式な仕様に変更される時に、これらのメソッドも変更されるかもということを示しているわけです。javax.net.sslパッケージの2つのメソッドもjavax.security.certパッケージに関連したメソッドです。HandshakeCompletedEvent.getPeerCertificateChainメソッドは返り値がX509Certificateクラスの配列なのです。今後はgetPeerCertificateChainメソッドではなく、同じクラスのgetPeerCertificatesメソッドを使うようにします。SSLSession.getPeerCertificateChainメソッドも同じで、代わりにgetPeerCertificatesメソッドを使うようにします。12.1をサポートしています。その関連で2つのクラスに定数が増えました。Character.UnicodeBlockクラスUnicodeBlockクラスはその名の通り、Unicodeのブロックを表す定数を定義しているクラスです。12.0で導入されたブロックが追加になりました。12.0で導入されたスクリプトが追加になりました。13が対応しているUnicodeのバージョンが12.0ではなく、12.1と教えていただきました。本文は修正してあります。対応しているUnicodeのバージョンはjava.lang.CharaccterクラスのJavadocに記述してあるそうです。13の場合は以下のように表記されています。CharacterクラスのJavadocより引用)Stringクラス前述したように、Stringクラスにはテキストブロック関連のメソッドが3つ追加されました。@DeprecatedのforRemoval=trueなので、コンパイル時に警告が出ます。5でstaticメソッドのformatメソッドが導入されましたが、formattedメソッドはそれのインスタンスメソッド版です。"2019-09-17\r\n"jshell>formatメソッドもformattedメソッドも内部ではjava.util.Formatterクラスのformatメソッドをコールしています。stripIndentメソッドは複数行からなる文字列の先頭文字がホワイトスペースだった場合、前詰めした文字列に変換するためのメソッドです。^--------------^jshell>なお、テキストブロックを使用すると、勝手に前詰めされます。コンパイル時にこのメソッドを使用しているかどうかまでは調べていないので、ぜひ調べてみてください。translateEscapesメソッドはエスケープシーケンスを変換するメソッドです。"\n"という2文字で表されているエスケープシーケンスをU+000Aに置き換えます。いうものの、このメソッドの使い道がイマイチよく分からないんですよね。いう時に使うんだろう?なお、このメソッドではUnicodeのエスケープは置き換えを行わないそうです。java.nioパッケージBuffer系のクラスにメソッドがいろいろと追加されました。BufferクラスBufferクラスにはsliceメソッドがオーバーロードされました。positionとlimitの間を切り出すメソッドでした。オーバーロードされたのは明示的にインデックスと長さを指定して切り出すために使用されます。実際には内部で、引数なしのsliceと同じような処理行っているので、使い勝手をよくするためのメソッドということですね。cap=3]jshell>同じ切り出しを引数なしのsliceメソッドと、引数ありのsliceメソッドでやってみました。Bufferクラスはアブストラクトクラスなので、ByteBufferクラスを使用しています。他のCharBufferクラスなどでも引数ありsliceメソッドがオーバーロードされています。ByteBuffer/CharBuffer/DoubleBuffer/FloatBuffer/IntBuffer/LongBuffer/ShortBufferクラスそれぞれのクラスにgetメソッドが2つ、putメソッドが2つオーバーロードされています。Bufferクラスに追加されたsliceメソッドは返り値の方がBufferクラスなのですが、ByteBufferクラスなどでオーバーロードされたメソッドは返り値の型がそれぞれのクラスなので、Bufferクラスでは定義できないのでした。使い道はどのクラスでも同じなので、ここではByteBufferクラスで説明します。length)今までのgetメソッドはpositionの位置から読み込みを行うか、インデックスを指定して1バイト読み込むかのどちらかしかありませんでした。新しくオーバーロードされたgetメソッドはインデックスを使用して第2引数のバイト配列に読み込みを行います。}jshell>ここでは、インデックス2から2バイト読み込んでます。putメソッドも同じで、今まではpositionから書き込みを行うか、インデックスを使用して1文字の書き込みを行うだけだったのが、インデックスを使用してバイト配列で書き込みが行えるようになりました。MappedByteBufferクラスMappedByteBufferクラスにはforceメソッドがオーバーロードされました。length)今までのforceメソッドは引数なしで、メモリにマップされた内容を強制的にファイルに書き出すというメソッドでした。オーバーロードされたforceメソッドはインデックスと長さを指定して強制的にファイルに書き出しを行います。java.nio.fileパッケージFileSystemsクラスFileSytemクラスでは、3種類のnewFileSystemメソッドがオーバーロードされています。loader)newFileSystemメソッドはFileSystemクラスのファクトリメソッドなのですが、今までは場所を指定するのにURIを使用していました。Pathインタフェースも使えたのですが、クラスローダ―を指定する必要がありました。13で追加された3種類はどれもPathインタフェースで場所を指定します。ZIPファイルやJARファイルをファイルシステムとみなして扱うような時に使用するメソッドなのですが、パスで指定できるようになったので、少しだけ扱いやすくなりました。<<以下、省略>>jshell>java.time.chronoパッケージJapaneseEraクラス日本の元号を表すクラスですが、令和が定数として追加されました。13からということです。REIWAjavax.annotationパッケージProcessingEnvironmentインタフェースアノテーションの処理を行う時に使用するインタフェースがProcessingEnvironmentインタフェースです。isPreviewEnabled()プレビュー機能を使用する時にはコンパイル/実行時に--enable-previewオプションを使用します。isPreviewEnabledメソッドは--enable-previewが指定されていればtrue、いなければfalseを返します。13が追加されました。RELEASE_13javax.lang.model.elementパッケージExecutableElementインタフェースExecutableElementインタフェースは、クラスやインタフェースのメソッド、コンストラクタなど実行できる要素を表すためのインタフェースです。asType()ExecutableElementインタフェースで表している実行要素がメソッドなのか、コンストラクタなのか、初期化子なのかを判別するために使用します。javax.toolsパッケージStandardJavaFileManagerインタフェースjavax.toolsパッケージはコンパイラ系のクラスが定義されているのですが、そこで使用するファイルマネージャがStandardJavaFileManagerインタフェースです。paths)これまで使われていたgetJavaFileObjectsFromPathメソッドは引数の型がIterableインタフェースだったのですが、Collectionインタフェースを引数にとるメソッドがオーバーロードされました。逆に引数の型がIterableインタフェースの方は@Deprecatedになっています。classLoader)いずれも名前空間を認識したDocumentBuilderFactoryオブジェクトを生成するファクトリメソッドです。他にもセキュリティ系のAPIに追加がありますが、よく分からないので省略します。13のAPIの変更をまとめてみましたが、やっぱり変更は少ないですね。Springが開催されました。Codeの次の日ですね。LoomのFiberについてプレゼンしました。SakurabaFiberはいわゆる軽量スレッドです。プレゼンではなぜ軽量スレッドが必要なのかという部分について、かなり時間をかけて説明しました。OSに強く結びついたThreadを使った場合、コンテキストスイッチにコストがかかります。時間もかかるし、メモリも多く使用します。Stackをすべて退避させたり、もどしたりする必要があるからです。Stackは、そのスレッドでコールされているメソッドコールのスタックで、メソッドで使われるローカル変数やオペランドスタックも含みます。OSがスレッドのスケジューリングを管理しているため、コンテキストスイッチがいつ行われているかもJava側からは管理することができません。そのために求められているのが、JVMで管理する軽量スレッド、つまりFiberというわけです。これに対し、Fiberを使えば、ワーカースレッド上で動作するため、スケジューリングはJVMで管理でき、状態の退避用のメモリも少なくてすみます。Frameworkが使用されます。コンテキストスイッチには処理の中断、再開のための仕組みが必要ですが、これはContinuationで行います。Continuationはいわゆる継続を実現させるための仕組みですが、JavaのContinuationは限定継続になります。プレゼンの中ではContinuationをかなり強引にwait-notifyAllと同じようなものと説明してしまったため、誤解させてしまったのではないかと反省しています。Continuationもwait-notifyAllも処理の中断・再開をするという機能はありますが、一般的なContinuationでできることは処理の中断・再開だけではありません。LoomではContinationを積極的に活用するようなシナリオはないように見えます。現状は、I/O待ちのためにパフォーマンスが落ちていることに対して、Fiberを使ってI/O待ちをなるべく解消することがメインの目的のようです。これは、処理の中断・再開を行うFiberのparkメソッド、unparkメソッドがデフォルトのアクセス制御であることからも分かります。park/unparkを使用しているのは、ReentrantLockクラスなどのロック系のクラスや、java.nio.channelパッケージのソケット通信などのクラスなどです。Codeのデモについても説明しました。JDKに含まれているHTTPサーバーであるcom.sun.net.httpserver.HttpSErverクラスを使用して、Fiberを指定しているだけです。これだけで、既存のExecutorServiceインタフェースを使用した場合よりもスレッド数やスループットが向上しました。いうものの、現状Fiberはそこまで速くありません。コンテキストスイッチが起きないようにうまくタスク分けして、I/O待ちも多重化するなどして待たなければいけないスレッドを最小化するなどのチューニングを行えば、Fiberより高いパフォーマンスを得ることができます。それをするには設計やチューニングなどの高度な知識や経験が求められます。Fiberを使うことで誰でも簡単にパフォーマンスを向上させられるということが、Fiberの意義の1つなのではないかと感じています。Stackを操作することも考えられているようなので、今後に期待したいですね。以下は会場やsli.doでの質問とその回答です。「この分野は素人なのですが」な質問!!!なんとか答えられてよかったですwさて、現状はFiberはシリアライザブルではないのですが、シリアライザブルにする計画があります。このため、ワークスレッドが変化することもありますし、処理途中のFiberを他のCPUに移動させてそこで再開というシナリオも考えられます。質問した伊藤さんも心配されていますが、ロガーのようにスタックトレースを保持させるようなものは、Fiberにするとやばいかもしれません。一般的な継続だとこれができるのですが、今のところJavaのFiberでは計画されていないようです。Stackをそのまま使っています。Stackを操作するバイトコードが必要になるはずですが、そこまでやるとかなり大がかりになってしまうためかもしれません。デフォルトではForkJoinPoolを利用してワークスレッドの割り当てを行っています。他のスレッドプールに置き換えることもできます。