Java 多线程总结

------- android培训java培训、期待与您交流! ----------

多线程两种方式:

 

继承Thread

定义一个子类继承Thread。复写Thread类中的run方法。调用该对像的start方法

start方法有两个作用,启动线程,调用run方法。

class Demo extends Thread {
    public void run() {
        for (int x = 0; x < 100; x++)
            System.out.println("demo " + x);
    }
}
class ThreadDemo1 {
    public static void main(String[] args) {
        Demo d = new Demo();
        d.start();
        for (int x = 0; x < 100; x++)
            System.out.println("main " + x);
    }
}

实现Runnable接口

覆盖Runnable接口的run方法

通过Thread类建立线程对象

将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数

调用Thread类的start方法开启线程并调用Runnerable接口自理的run方法

class Demo implements Runnable {
    public void run() {
        for (int x = 0; x < 100; x++)
            System.out.println("demo " + x);
    }
}
class ThreadDemo2 {
    public static void main(String[] args) {
        Demo d = new Demo();
        Thread t = new Thread(d);
        t.start();
        for (int x = 0; x < 100; x++)
            System.out.println("main " + x);
    }
}

多线程编程的时候,不同的线程,可能会访问同一资源,这样就可能导致一些问题:数据安全、死锁、等待等。

所以要对多线程共同操作的对象加锁:

class Ticket implements Runnable {
    private int ticket = 1000;
    Object obj = new Object();
    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                    }
                    System.out.println(Thread.currentThread().getName()
                    + " sale: " + ticket--);
                }
                else
                    break;
            }
        }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Ticket tick = new Ticket();
        Thread t1 = new Thread(tick);        t1.start();
        Thread t2 = new Thread(tick);        t2.start();
        Thread t3 = new Thread(tick);        t3.start();
        Thread t4 = new Thread(tick);        t4.start();
    }
}

值得注意的是:

synchronized (obj)里面的obj其实是一个锁。如果要让不同的线程的共享数据安全,那么对同一个数据操作的锁必须是同一把锁。

Synchronized 不光可以加在代码外,也可以加载方法上。加载在方法上,虽然没有写锁对象,但实际上锁对象是this。对于静态方法锁对象是本类。

一个死锁的代码:

class MyLock {
    static Object lockA = new Object();
    static Object lockB = new Object();
}
class DeadLock implements Runnable {
    private boolean flag;
    DeadLock(boolean flag) {
        this.flag = flag;
    };
    public void run() {
        if (flag) {
            synchronized (MyLock.lockA) {
                System.out.println("ifout");
                synchronized (MyLock.lockB) {
                    System.out.println("ifin");
                }
            }
        }
        else {
            synchronized (MyLock.lockB) {
                System.out.println("elseout");
                synchronized (MyLock.lockA) {
                    System.out.println("elsein");
                }
            }
        }
    }
}
class DeadLockDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread(new DeadLock(true));
        Thread t2 = new Thread(new DeadLock(false));
        t1.start();
        t2.start();
    }
}

对于有多个消费者和多个生产者的情况,如果想要生产和消费交替发生。就需要LocK类和Condition类,下面是毕老师的一个双线程交替运行的代码,写得非常好,值得多看几遍:

import java.util.concurrent.locks.*;
class ProducerConsumerDemo {
    public static void main(String[] args) {
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(pro);
        Thread t3 = new Thread(con);
        Thread t4 = new Thread(con);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class Resource {
    private String name;
    private int count = 1;
    private boolean flag = false;
    private Lock lock = new ReentrantLock();
    private Condition condition_pro = lock.newCondition();
    private Condition condition_con = lock.newCondition();
    public void set(String name) throws InterruptedException {
        lock.lock();
        try {
            while (flag)
                condition_pro.await();// t1,t2
            this.name = name + "--" + count++;
            System.out.println(Thread.currentThread().getName() + "...生产者.."
                    + this.name);
            flag = true;
            condition_con.signal();
        } finally {
            lock.unlock();// 释放锁的动作一定要执行。
        }
    }
    // t3 t4
    public void out() throws InterruptedException {
        lock.lock();
        try {
            while (!flag)
                condition_con.await();
            System.out.println(Thread.currentThread().getName()
                    + "...消费者........." + this.name);
            flag = false;
            condition_pro.signal();
        } finally {
            lock.unlock();
        }
    }
}
class Producer implements Runnable {
    private Resource res;
    Producer(Resource res) {
        this.res = res;
    }
    public void run() {
        while (true) {
            try {
                res.set("+商品+");
            } catch (InterruptedException e) {
            }
        }
    }
}
class Consumer implements Runnable {
    private Resource res;
    Consumer(Resource res) {
        this.res = res;
    }
    public void run() {
        while (true) {
            try {
                res.out();
            } catch (InterruptedException e) {
            }
        }
    }
}

 

 

posted @ 2012-12-30 17:03  qinbin  阅读(307)  评论(0编辑  收藏  举报