Java简明教程 12.多线程(multithreading)

单线程和多线程

关于它们的区别,zhihu上有一个回答,我认为十分不错,如下:

1. 单进程单线程:一个人在一个桌子上吃菜。

2. 单进程多线程:多个人在同一个桌子上一起吃菜。

3. 多进程单线程:多个人每个人在自己的桌子上吃菜。



多线程的问题是多个人同时吃一道菜的时候容易发生争抢.例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。



例子:

多线程:

浏览器浏览一个页面,里面有很多图片,多线程,每个线程下载一副图片,他们相当于一个桌子上不同的菜。



多进程:

浏览器开了多个标签浏览不同网站,多进程,因为他们相当于“不同的桌子” 



原文链接:http://www.zhihu.com/question/19901763

 

如何创建线程

方式1:

MultiThreading.java

public class MultiThreading {

    public static void main(String[] args) {

        NewThread thread1 = new NewThread();

        NewThread thread2 = new NewThread();



        thread1.start();

        thread2.start();

    }   

}



class NewThread extends Thread {                                //继承Thread类

    private static int num = 0;

    public NewThread() {

        super("THread:" + ++num);                               //通过Thraed的构造方法,初始化线程的名字

                                                                //public Thread(String name)

    }

    



    //重写Thread的run()方法,然后通过Thread的start()方法调用run()方法,实现多线程

    @Override

    public void run() {

        while (true) {

            System.out.println(super.getName() + " is running~");//getName():获取线程的名字

        }   

    }   

}

 

方式2:实现Runnable接口

MultiThreading2.java

public class MultiThreading2 {

    public static void main(String[] args) {

        Thread thread1 = new Thread(new NewThread("线程1"));

        Thread thread2 = new Thread(new NewThread("线程2"));



        thread1.start();

        thread2.start();

    }   

}



class NewThread implements Runnable {

    private String threadName = null;



    public NewThread(String threadName) {

        this.threadName = threadName;

    }   



    @Override

    public void run() {

        while (true) {

            System.out.println(this.threadName + " is running~");

        }

    }   

}

看下Thread类的构造方法,   "public Thread(Runnable target)", 不难懂上面那个小例子.

 

synchronized

我们考虑一个问题,如果一个桌子上有三个人(Person)在吃100个汉堡包(Hamburger), 当只有一个汉堡包的时候,其中的一个人判断还有一个汉堡包(hamburgerNum > 0), 所以执行了eatHamburger()操作, 而另一个人在这之前,也判断了还有一个汉堡包(hamburgerNum > 0), 想要执行eatHamburger()操作的时候, 那个汉堡包已经被别人吃了, 那么这个时候 (hamburgerNum--) 汉堡包的数量不就成了负数了吗? 这明显是不行的.

也就是说, "判断和吃"这个两个操作, 需要一个人一起执行成功后, 才能让另一个人执行. 所以我们需要把它们 "绑在一起", 也就是"锁"起来.这里就不要用到 "syncronized"(同步)这个修饰符了

 

Test.java

public class Test {

    public static void main(String[] args) {

        Hamburger h = new Hamburger(100);

        Person p1 = new Person(h);

        Person p2 = new Person(h);

        Person p3 = new Person(h);



        p1.start();

        p2.start();

        p3.start();

    }   

}



class Person extends Thread {                       //继承Thread类,重写run()方法,通过调用Thread的start()方法,创建多个线程

    private int count = 0;                          //记录这个人吃了多少个汉堡包

    private String name = "小明";

    private static int num = 0;                     //这里需要使用static修饰

    private Hamburger hamburger = null;





    public Person(Hamburger hamburger) {

        this.hamburger = hamburger;

        this.name = this.name + (++num) + "号";

    }   



    @Override

    public void run() {

        while (true) {

            if (hamburger.eatHambergerNum()) {

                System.out.println(this.name + ": eat 1 Hamburger.");

                count++;

                try {

                    sleep((int)Math.random() * 100);                    //鄙人不明白为什么要这个句子?如果知道的请告知

                                                                        //或者,不需要这个句子?比人测试了,这个句子似乎没什么作用

                                                                        //线程不管"sleep"不"sleep",都不会永远分配给进程的霸占cpu吧

                } catch(InterruptedException e) {

                    e.printStackTrace();

                }

            } else {

                break;

            }

        }

        System.out.println(this.name + ": " + count);

    }

}



class Hamburger {

    private int hamburgerNum = 0;



    public Hamburger(int num) {

        this.hamburgerNum = num;

    }





    //注意这里使用了 "synchronized"修饰! "synchronized"也可以修饰语句块  用法: synchronized(对象) {}

    public synchronized boolean eatHambergerNum() {

        if (hamburgerNum > 0) {

            hamburgerNum--;

            return true;

        } else {

            return false;

        }

    }

}

 

参考:http://www.cnblogs.com/vamei/archive/2013/04/15/3000898.html

你可能感兴趣的:(reading)