協程Coroutines_java

最近想研究一下Coroutines(協程)並在java項目中進行應用,但是發現現在大部分資料講的是unity、lua、alang等方面的應用,java上講的確實不太多。所以今天想把這幾天的學習結果寫出來和大家一起分享。可能有一些理解不一定對,請大家批評指正。


大家知道,線程是程序執行流的最小單位,但是可以把協程認爲是比線程更小的執行單元。

協程和線程可以設計成1:N的模式,即一個線程容器中可以放置多個協程。

每個協程有自己的上下文信息,可以在協程之間進行切換,

而且這種切換是用戶態的切換,不像線程切換需要深入到操作系統內核纔可以,

所以協程比線程更加節省資源,更加快速。而且很適合項目中有低速IO和高速CPU進行協調調度的問題。


目前我瞭解到可以在java程序中應用的協程組件有以下幾種:

javaflow:http://commons.apache.org/sandbox/commons-javaflow/

Coroutines:https://github.com/offbynull/coroutines

Kilim:https://github.com/kilim/kilim

我個人目前只嚐了前面兩種,其中Coroutines中作者在javaflow問題的基礎上重新設計的一種,比javaflow在狀態的變化中運行的更加快速、而且提供了maven和ant兩種方法、更好的支持java8等優點。


以下我以Coroutines組件爲例說一下具體實現過程:


我本身用的是ant插件,其中主要jar包如下:

lib/ant-plugin-1.1.1-shaded.jar

lib/commons.jar

lib/user-1.1.1.jar


1、創建一個工程

2、引入以上jar包

3、編寫相應程序,如下:

import com.offbynull.coroutines.user.Continuation;
import com.offbynull.coroutines.user.Coroutine;
import com.offbynull.coroutines.user.CoroutineRunner;

public class App implements Coroutine {
	public static void main(String[] args) {
		CoroutineRunner r = new CoroutineRunner(new App());
		boolean flag = r.execute();
		while (flag) {
			flag = r.execute();
		}
	}

	public void run(Continuation c) throws Exception {
		System.out.println("started");
		for (int i = 0; i < 10; i++) {
			echo(c, i);
		}
	}

	private void echo(Continuation c, int x) {
		System.out.println(x);
		c.suspend();
	}
}

4、編寫build.xml,對class文件進行重新裝配

<?xml version="1.0" encoding="UTF-8"?>
<project name="CoroutiesTest" default="run" basedir=".">
	<description>use jar test</description>
	<property name="src" value="src" />
	<property name="classes" value="bin/classes" />
	
	<target name="clean">
		<delete dir="${classes}" />
	</target>

	<pathconvert property="lib" pathsep=" ">
		<mapper>
			<chainedmapper>
				<flattenmapper />
				<globmapper from="*" to="lib/*" />
			</chainedmapper>
		</mapper>
		<fileset dir="lib">
			<include name="*.jar" />
		</fileset>
	</pathconvert>

	
	<property name="libs" value="${lib}" />

	<echo>libs   ${libs}</echo>

	<target name="init">
		<mkdir dir="${classes}" />
	</target>

		
	<taskdef name="InstrumentTask" classname="com.offbynull.coroutines.antplugin.InstrumentTask">
			<classpath>
				<fileset dir="lib">
					<include name="*.jar" />
				</fileset>
			</classpath>
		</taskdef>

		<target name="compile" depends="init" description="comile target">
			<javac srcdir="${src}" destdir="${classes}" includeantruntime="true">
				<classpath>
					<fileset dir="lib">
						<include name="*.jar" />
					</fileset>
				</classpath>
			</javac>

			<InstrumentTask classpath="." sourceDirectory="${classes}" targetDirectory="${classes}"/>
		</target>

	<tstamp />

	<property name="jarfilename" value="${ant.project.name}.jar" />
	<target name="jar" depends="compile" description="make jar file">
		<jar jarfile="${jarfilename}" basedir="${classes}">
			<manifest>
				<attribute name="Main-Class" value="App" />
				<attribute name="Class-Path" value="${libs}" />
			</manifest>
		</jar>
	</target>

	<target name="run" depends="jar">
		<java jar="${jarfilename}" fork="true">
		</java>
	</target>

</project>


5、運行結果:

Buildfile: D:\MyProgram\java8\CoroutiesTest\build.xml
     [echo] libs   lib/ant-plugin-1.1.1-shaded.jar lib/commons.jar lib/user-1.1.1.jar
init:
compile:
    [javac] Compiling 1 source file to D:\MyProgram\java8\CoroutiesTest\bin\classes
[InstrumentTask] Classpath for instrumentation is as follows: [., D:\Program Files\Java\jre8\lib\charsets.jar, D:\Program Files\Java\jre8\lib\deploy.jar, D:\Program Files\Java\jre8\lib\ext\access-bridge-64.jar, D:\Program Files\Java\jre8\lib\ext\cldrdata.jar, D:\Program Files\Java\jre8\lib\ext\dnsns.jar, D:\Program Files\Java\jre8\lib\ext\jaccess.jar, D:\Program Files\Java\jre8\lib\ext\jfxrt.jar, D:\Program Files\Java\jre8\lib\ext\localedata.jar, D:\Program Files\Java\jre8\lib\ext\nashorn.jar, D:\Program Files\Java\jre8\lib\ext\sunec.jar, D:\Program Files\Java\jre8\lib\ext\sunjce_provider.jar, D:\Program Files\Java\jre8\lib\ext\sunmscapi.jar, D:\Program Files\Java\jre8\lib\ext\sunpkcs11.jar, D:\Program Files\Java\jre8\lib\ext\zipfs.jar, D:\Program Files\Java\jre8\lib\javaws.jar, D:\Program Files\Java\jre8\lib\jce.jar, D:\Program Files\Java\jre8\lib\jfr.jar, D:\Program Files\Java\jre8\lib\jfxswt.jar, D:\Program Files\Java\jre8\lib\jsse.jar, D:\Program Files\Java\jre8\lib\management-agent.jar, D:\Program Files\Java\jre8\lib\plugin.jar, D:\Program Files\Java\jre8\lib\resources.jar, D:\Program Files\Java\jre8\lib\rt.jar, D:\Program Files\Java\jre8\lib\security\local_policy.jar, D:\Program Files\Java\jre8\lib\security\US_export_policy.jar]
[InstrumentTask] Creating instrumenter...
[InstrumentTask] Processing D:\MyProgram\java8\CoroutiesTest\bin\classes ... 
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\App.class
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\ICallBack.class
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\MessageProcess$1.class
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\MessageProcess.class
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\RemoteClass.class
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\Test$1.class
[InstrumentTask] Instrumenting D:\MyProgram\java8\CoroutiesTest\bin\classes\Test.class
jar:
      [jar] Building jar: D:\MyProgram\java8\CoroutiesTest\CoroutiesTest.jar
run:
     [java] started
     [java] 0
     [java] 1
     [java] 2
     [java] 3
     [java] 4
     [java] 5
     [java] 6
     [java] 7
     [java] 8
     [java] 9
BUILD SUCCESSFUL
Total time: 3 seconds


好了,大功告成!希望能給想學習協程的同行們提供幫助,也希望大家能夠把一些自己的理解想出來,大家一起分享學習,共同進步,謝謝!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章