java多线程论文_Java5 多线程之入门篇-论文

Java5 多线程之入门篇

Java5 多线程之入门篇

首先回顾一下JDK1.5之前的线程相关的知识:

1 线程的入门.

什么是线程,线程就是程序执行的线索,Java是面向对象的语言什么类来表示这样一个东西呢?Thread.

通过start()方法启动它,线程所要执行的任务放在run()方法里面,下面可以看一下run()方法里面的源码

创建线程的两种传统方式(注: Runnable类并不是一个线程,它只是线程一个执行单元):

打开Thread的构造方法,

然后可以跟进看到init()方法具体的实现.其中有一行代码就是对target(Runnable类型)的赋值,因为线程所执行的任务都在run()方法里面,那么在run()方法里面,target就不为null,然后就调用了Runnale的run()方法.因为我们重写了Runnable的run()方法,那么最终执行的就是我们所覆写的run()方法.具体代码如下:

如果我们同时实现了Thread的run()方法又同时覆盖了Runnable的run()方法.那么到底会执行哪个的run()方法呢?

根据Java的多态,肯定执行的是Thread的run()方法.因为我们覆写了Thread的run()方法,那么所执行的就是我们run()方法,而不是

2 传统的定时器:

定时器通过Timer这个类来描述,通过schedule()方法来调度,定时执行的任务通过TimerTask来定义.

下面来实现一个简单的定时器,功能如下,每隔2秒执行一次,之后隔4秒执行一次,然后又隔2秒,就这样轮循下去.具体用法可以查看API里面有详细介绍.

[java] view plaincopy 01.public static void main(String[] args) {

02.    new Timer().schedule(new MyTimerTask(), 2000);

03.    try {

04.        while (true) {

05.        System.out.println(new Date().getSeconds());

06.        Thread.sleep(1000);

07.    }

08.} catch (InterruptedException e) {

09.    e.printStackTrace();

10.        }

11.    }

12.    }

13.class MyTimerTask extends TimerTask {

14.    static int count = 0;

15.    @Override

16.    public void run() {

17.        count = (count + 1) % 2;//count=0或1

18.        System.out.println("boming");

19.        Timer timer = new Timer();

20.        timer.schedule(new MyTimerTask(), 2000 + (2000) * count);

21.    }

3 线程之间的互斥和同步通信

当两个线程去同时操作一个字符串,那么可能会出现线程安全问题.这样的情况可以用银行转帐来解释.

下面的代码就会出现问题,

[java] view plaincopy 01.public static void main(String[] args) {

02.final Outputer outputer = new Outputer();

03.new Thread() {

04.@Override

05.public void run() {

06.while (true) {

07.try {

08.Thread.sleep(100);

09.} catch (InterruptedException e) {

10.e.printStackTrace();

11.}

12.outputer.print("zhangsan");

13.}

14.}

15.}.start();

16.new Thread() {

17.@Override

18.public void run() {

19.while (true) {

20.try {

21.Thread.sleep(100);

22.} catch (InterruptedException e) {

23.e.printStackTrace();

24.}

25.outputer.print("zhangxiaoxiang");

26.}

27.}

28.}.start();

29.}

30.}

31.class Outputer {

32.public void print(String name) {

33.for (int i = 0; i < name.length(); i++) {

34.System.out.print(name.charAt(i));

35.}

36.System.out.println();// 打印完字符串换行

37.}

38.}

我们使用两个线程去调用print(String name)方法,当第一个方法还没有执行完毕,第二个方法来执行,那么打印出来的name就会出现为问题.如下图所示,

现在我们要实现的是,只有当第一个线程执行完毕后,第二个线程才能执行print(String name)方法,这就必须互斥或者说同步.

我们知道实现同步可以使用同步代码块或者同步方法,想到同步(Synchronized)那么自然而然就想到同步监视器.

这是两个很重要的概念.

现在我们来改造上面Outputer的print(String name)方法.

[java] view plaincopy 01.public void print(String name) {

02.//synchronized()里面的参数就是同步监视器

03.//然而这里使用name作为同步监视器是不行的,

04.//因为要实现原子性(互斥)必须要使用同一个监视器对象

05.//当第一个线程来执行该代码块,name对象是一个String对象

06.//当第二个线程来执行,name对象又是另一个String对象,

07.//这样就不能实现同步

08.synchronized (name) {

09.for (int i = 0; i < name.length(); i++) {

10.System.out.print(name.charAt(i));

11.}

12.System.out.println();// 打印完字符串换行

13.}

14.}

执行结果如下所示:

我们可以通过this关键字作为同步监视器,因为从上面定义两个线程的代码来看,我们只new了一次Outputer对象,所以this代表同一个对象.

现在来通过同步方法来实现同步,

[java] view plaincopy 01.//同步方法也同样也有同步监视器,它是this

02.public synchronized void print2(String name) {

03.    for (int i = 0; i < name.length(); i++) {

04.        System.out.print(name.charAt(i));

05.    }

06.    System.out.println();// 打印完字符串换行

07.}

把第二个线程改成使用print2(String name)方法.这样的话就需要p

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值