加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Java 多线程一:基础

发布时间:2023-04-17 11:37:10 所属栏目:教程 来源:
导读:顺序(sequential)用于表示多个操作『依次』处理。比如把十个操作交给一个人处理,这个人要一个一个地按顺序来处理。

并发(concurrent)相对于顺序和并行来说比较抽象,用于表示『将一个操作分割成多个部分并且
顺序(sequential)用于表示多个操作『依次』处理。比如把十个操作交给一个人处理,这个人要一个一个地按顺序来处理。

并发(concurrent)相对于顺序和并行来说比较抽象,用于表示『将一个操作分割成多个部分并且允许无序处理』。比如将十个操作分成相对独立的两类,这样便可以开始并发处理了。如果是一个人来处理,这个人就是顺序处理分开的并发操作,而如果是两个人。这两个人就可以并行处理同一操作。

仅程是计算机资源分配的基本单位;

线程是资源调度执行的基本单位,也可以说:线程是一个程序里面不同的执行路径,在多个线程之间共享过程中的资源;

协程是一种用户的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。协程在子程序内部可中断的,然后转而执行别的子程序,在适当的时候再返回来接着执行。

协程的特点在于是一个线程执行,那和多线程比,协程有如下优势:

优势一:极高的执行效率:因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显;

优势二:不需要多线程的锁机制:因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比其他的多线程操作系统高出来很多。

注意:协程避免了无意义的调度,由此可以提高性能,但是程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多 cpu 的能力。

一个简单的协程示例, 代码如下:

注:

需要引入quasar-core依赖包。

如果在 Java SE 16 以及更高版本上运行,需要增加如下参数

--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
package git.snippets.juc;
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.channels.Channel;
import co.paralleluniverse.strands.channels.Channels;
import java.util.concurrent.ExecutionException;
/**
 * Java协程示例
 * JDK 11 ~ JDK 15 没问题,
 *
 * JDK 16 开始,需要增加如下参数
 *
 * --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
 *
 * @since jdk11
 * 需要引入:quasar-core依赖包
 */
public class FiberSample {
    private static void printer(Channel<Integer> in) throws SuspendExecution, InterruptedException {
        Integer v;
        while ((v = in.receive()) != null) {
            System.out.println(v);
        }
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution {
        //定义两个Channel
        try (Channel<Integer> naturals = Channels.newChannel(-1); Channel<Integer> squares = Channels.newChannel(-1)) {
            //运行两个Fiber实现.
            new Fiber(() -> {
                for (int i = 0; i < 10; i++) {
                    naturals.send(i);
                }
                naturals.close();
            }).start();
            new Fiber(() -> {
                Integer v;
                while ((v = naturals.receive()) != null) {
                    squares.send(v * v);
                }
                squares.close();
            }).start();
            printer(squares);
        }
    }
}

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章