Yuque Archive
寻常的路

开始使用多线程

查看线程

新建Java项目,新建Test类,查看main方法启动的线程名称:

src/test/Test.java

控制台会打印出"main",这就是此线程的名称。

使用多线程

要自己创建进程,有两种老生常谈的方法。

继承Thread类

新建MyThread类,继承Thread类,重写run方法:

src/test/MyThread.java

run方法会创建一个用户线程。再创建一个Run类,运行这个创建用户线程的方法:

src/test/Run.java

程序的运行结果,控制台往往会先打印"运行结束!",再打印出"MyThread",因为线程的执行顺序是随机的。

实现Runnable接口

Thread实现了Runnable接口,因此我们使用两种方法的不同之处在于,类只能单继承,而接口可以多实现。这是Java的特性之一。

创建MyRunnable类,测试线程的创建:

src/test/MyRunnable.java

没有什么特别之处,与继承方式类似。

然后在Run类中加入或修改一些代码,启动线程:

注意runnable对象作为参数传递给Thread对象,才可以运行。

数据安全

多线程不共享数据

循环结构即为同步操作,不受多线程影响。在test1包下新建MyThread类,做第二轮试验:

src/test1/MyThread.java

线程运行起来之后会循环5次,进行count的递减输出。

在测试类Run中启动3个线程:

src/test1/Run.java

控制台的输出结果应为15条记录,并且各线程是乱序的。

共享数据的情况

在MyThread中做少量修改,将while循环删掉,此时的run方法:

src/test1/MyThread.java

要实现多线程共享数据,Run类也要做出一些修改:

src/test1/Run.java

这里将MyThread实例作为参数传入Thread的构造方法。运行程序,发现是乱序的,并且有可能出现多个线程计算值相同的情况。(如果没有,多运行几次)

synchronized

要解决多线程共享数据不安全的问题,可以使用同步关键字。只需在run方法前声明:

src/test1/MyThread.java

再次运行Run类,程序正常运行,结果符合预期。

参考:

  • 《Java多线程编程核心技术》