JAVA线程

JAVA线程

- 1.实现

一种是继承Thread类;
实现Runnable接口;
实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值:

public class ThreadFuture {

    public static void main(String[] args) throws Exception {

        ExecutorService service = Executors.newFixedThreadPool(1);
        Future<Integer> result = service.submit(new MyTask(1));
        if (!result.isDone()) {//等待结果
            System.out.println("result = " + result.get());
        }

    }

    static class MyTask implements Callable<Integer> {

        private int myCount;

        public MyTask(int count) {
            this.myCount = count;
        }

        @Override
        public Integer call() throws Exception {
            Thread.sleep(1000);
            return myCount + 1;
        }

    }

}

2.线程同步的方法

锁:内置锁(方法锁,对象锁,类锁),
重入锁:

            Lock lock = new ReentrantLock();
                try {
                    lock.lock();
                    。。。。

         } finally {
              lock.unlock();}

synchronized块:
信号量:

/** 
 * 通过以下两种方式获得许可 
 * acquire()  
 * tryAcquire() 
 * @author user 
 * 
 */  
public class SemaphoreTest {  

    private final Set<Integer> set;  

    private final Semaphore sem;  

    public SemaphoreTest(int bound){  
        this.set = Collections.synchronizedSet(new HashSet<Integer>());  
        sem = new Semaphore(bound);       
    }  

    public boolean add(Integer o) throws InterruptedException{  
        sem.acquire(); //如果信号量已被用光阻塞  
        boolean wasAdded = false;  
        try{  
            wasAdded = set.add(o);  
            return wasAdded;  
        } finally {  
            if(!wasAdded){  
                sem.release();  
            }  
        }  
    }  

    public boolean addNoAwait(Integer o) throws InterruptedException{  
        boolean wasAdded = false;  
        if(sem.tryAcquire()){             
            try{  
                wasAdded = set.add(o);  
            } finally {  
                if(!wasAdded){  
                    sem.release();  
                }  
            }  
        }  
        return wasAdded;  
    }  

    public boolean remove (Integer o){  
        boolean wasRemoved = set.remove(o);  
        if(wasRemoved){  
            sem.release();  
        }  
        return wasRemoved;  
    }  

    /** 
     * @param args 
     * @throws InterruptedException  
     */  
    public static void main(String[] args) throws InterruptedException {  
        SemaphoreTest test = new SemaphoreTest(5);  
        for(int i = 0; i < 10; i++){  
//          System.err.println("add " + i + "=" +test.add(i));  
            System.err.println("add " + i + "=" +test.addNoAwait(i));  
        }  
    }  

}  

3.ThreadLocal
-------------

不同线程中访问同一个ThreadLocal的set和get方法,它们对ThreadLocal所做的读写操作仅限于各自线程的内部,这就是为什么ThreadLocal可以在多个线程中互不干扰地存储和修改数据
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

….

public static Looper myLooper() {
    return sThreadLocal.get();
}

4.ThreadPool用法与优势
=================

  引入的好处:
  1)提升性能。创建和消耗对象费时费CPU资源
  2)防止内存过度消耗。控制活动线程的数量,防止并发线程过多。

public class ThreadPool {

private int threadPoolMaxSize;
private List<RunTask> taskQueue;
private WorkThread[] worker;
private static ThreadPool threadPool;

public ThreadPool(int size) {
    this.threadPoolMaxSize = size;
    taskQueue = new LinkedList<RunTask>();
    worker = new WorkThread[size];
    for (int i = 0; i < worker.length; i++) {
        worker[i] = new WorkThread();
        worker[i].start();
    }
}

public static ThreadPool getThreadpool(int size) {
    if (threadPool == null) {
        threadPool = new ThreadPool(size);
    }
    return threadPool;
}

public void destory() {
    for (int i = 0; i < worker.length; i++) {
        worker[i].isRunning = false;
    }
    taskQueue.clear();// ?????清除队列
}

public void addTask(Runnable r) {
    synchronized (taskQueue) {
        taskQueue.add((RunTask) r);
    }
}

class WorkThread extends Thread {
    boolean isRunning = true;

    @Override
    public void run() {
        synchronized (taskQueue) {// ???需要同步
            while (isRunning && !taskQueue.isEmpty()) {
                Runnable runnable = taskQueue.remove(0);
                runnable.run();
            }
        }
    }
}

class RunTask implements Runnable {

    @Override
    public void run() {

        // ....
    }

}

}

5.wait()和sleep()的区别

① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。

② 锁: 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。

Thread.sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。

③ 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。

synchronized(x){
x.notify()
//或者wait()
}
6.生产者消费者模式
采用某种机制保护生产者和消费者之间的同步:

/** 
 * 仓库类Storage实现缓冲区 
 *  
 * Email:530025983@qq.com 
 *  
 * @author MONKEY.D.MENG 2011-03-15 
 *  
 */  
public class Storage  
{  
    // 仓库最大存储量  
    private final int MAX_SIZE = 100;  

    // 仓库存储的载体  
    private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>(  
            100);  

    // 生产num个产品  
    public void produce(int num)  
    {  
        // 如果仓库剩余容量为0  
        if (list.size() == MAX_SIZE)  
        {  
            System.out.println("【库存量】:" + MAX_SIZE + "/t暂时不能执行生产任务!");  
        }  

        // 生产条件满足情况下,生产num个产品  
        for (int i = 1; i <= num; ++i)  
        {  
            try  
            {  
                // 放入产品,自动阻塞  
                list.put(new Object());  
            }  
            catch (InterruptedException e)  
            {  
                e.printStackTrace();  
            }  

            System.out.println("【现仓储量为】:" + list.size());  
        }  
    }  

    // 消费num个产品  
    public void consume(int num)  
    {  
        // 如果仓库存储量不足  
        if (list.size() == 0)  
        {  
            System.out.println("【库存量】:0/t暂时不能执行生产任务!");  
        }  

        // 消费条件满足情况下,消费num个产品  
        for (int i = 1; i <= num; ++i)  
        {  
            try  
            {  
                // 消费产品,自动阻塞  
                list.take();  
            }  
            catch (InterruptedException e)  
            {  
                e.printStackTrace();  
            }  
        }  

        System.out.println("【现仓储量为】:" + list.size());  
    }  

    // set/get方法  
    public LinkedBlockingQueue<Object> getList()  
    {  
        return list;  
    }  

    public void setList(LinkedBlockingQueue<Object> list)  
    {  
        this.list = list;  
    }  

    public int getMAX_SIZE()  
    {  
        return MAX_SIZE;  
    }  
}  
----------

/** 
 * 生产者类Producer继承线程类Thread 
 *  
 * Email:530025983@qq.com 
 *  
 * @author MONKEY.D.MENG 2011-03-15 
 *  
 */  
public class Producer extends Thread  
{  
    // 每次生产的产品数量  
    private int num;  

    // 所在放置的仓库  
    private Storage storage;  

    // 构造函数,设置仓库  
    public Producer(Storage storage)  
    {  
        this.storage = storage;  
    }  

    // 线程run函数  
    public void run()  
    {  
        produce(num);  
    }  

    // 调用仓库Storage的生产函数  
    public void produce(int num)  
    {  
        storage.produce(num);  
    }  

    // get/set方法  
    public int getNum()  
    {  
        return num;  
    }  

    public void setNum(int num)  
    {  
        this.num = num;  
    }  

    public Storage getStorage()  
    {  
        return storage;  
    }  

    public void setStorage(Storage storage)  
    {  
        this.storage = storage;  
    }  
}  
/** 
 * 消费者类Consumer继承线程类Thread 
 *  
 * Email:530025983@qq.com 
 *  
 * @author MONKEY.D.MENG 2011-03-15 
 *  
 */  
public class Consumer extends Thread  
{  
    // 每次消费的产品数量  
    private int num;  

    // 所在放置的仓库  
    private Storage storage;  

    // 构造函数,设置仓库  
    public Consumer(Storage storage)  
    {  
        this.storage = storage;  
    }  

    // 线程run函数  
    public void run()  
    {  
        consume(num);  
    }  

    // 调用仓库Storage的生产函数  
    public void consume(int num)  
    {  
        storage.consume(num);  
    }  

    // get/set方法  
    public int getNum()  
    {  
        return num;  
    }  

    public void setNum(int num)  
    {  
        this.num = num;  
    }  

    public Storage getStorage()  
    {  
        return storage;  
    }  

    public void setStorage(Storage storage)  
    {  
        this.storage = storage;  
    }  
}  
/** 
 * <a href="http://lib.csdn.net/base/softwaretest" class='replace_word' title="软件测试知识库" target='_blank' style='color:#df3434; font-weight:bold;'>测试</a>类Test 
 *  
 * Email:530025983@qq.com 
 *  
 * @author MONKEY.D.MENG 2011-03-15 
 *  
 */  
public class Test  
{  
    public static void main(String[] args)  
    {  
        // 仓库对象  
        Storage storage = new Storage();  

        // 生产者对象  
        Producer p1 = new Producer(storage);  
        Producer p2 = new Producer(storage);  
        Producer p3 = new Producer(storage);  
        Producer p4 = new Producer(storage);  
        Producer p5 = new Producer(storage);  
        Producer p6 = new Producer(storage);  
        Producer p7 = new Producer(storage);  

        // 消费者对象  
        Consumer c1 = new Consumer(storage);  
        Consumer c2 = new Consumer(storage);  
        Consumer c3 = new Consumer(storage);  

        // 设置生产者产品生产数量  
        p1.setNum(10);  
        p2.setNum(10);  
        p3.setNum(10);  
        p4.setNum(10);  
        p5.setNum(10);  
        p6.setNum(10);  
        p7.setNum(80);  

        // 设置消费者产品消费数量  
        c1.setNum(50);  
        c2.setNum(20);  
        c3.setNum(30);  

        // 线程开始执行  
        c1.start();  
        c2.start();  
        c3.start();  
        p1.start();  
        p2.start();  
        p3.start();  
        p4.start();  
        p5.start();  
        p6.start();  
        p7.start();  
    }  
}  


------

【库存量】:0 暂时不能执行生产任务!  
【库存量】:0 暂时不能执行生产任务!  
【现仓储量为】:1  
【现仓储量为】:1  
【现仓储量为】:3  
【现仓储量为】:4  
【现仓储量为】:5  
【现仓储量为】:6  
【现仓储量为】:7  
【现仓储量为】:8  
【现仓储量为】:9  
【现仓储量为】:10  
【现仓储量为】:11  
【现仓储量为】:1  
【现仓储量为】:2  
【现仓储量为】:13  
【现仓储量为】:14  
【现仓储量为】:17  
【现仓储量为】:19  
【现仓储量为】:20  
【现仓储量为】:21  
【现仓储量为】:22  
【现仓储量为】:23  
【现仓储量为】:24  
【现仓储量为】:25  
【现仓储量为】:26  
【现仓储量为】:12  
【现仓储量为】:1  
【现仓储量为】:1  
【现仓储量为】:2  
【现仓储量为】:3  
【现仓储量为】:4  
【现仓储量为】:5  
【现仓储量为】:6  
【现仓储量为】:7  
【现仓储量为】:27  
【现仓储量为】:8  
【现仓储量为】:6  
【现仓储量为】:18  
【现仓储量为】:2  
【现仓储量为】:3  
【现仓储量为】:4  
【现仓储量为】:5  
【现仓储量为】:6  
【现仓储量为】:7  
【现仓储量为】:8  
【现仓储量为】:9  
【现仓储量为】:10  
【现仓储量为】:16  
【现仓储量为】:11  
【现仓储量为】:12  
【现仓储量为】:13  
【现仓储量为】:14  
【现仓储量为】:15  
【现仓储量为】:1  
【现仓储量为】:2  
【现仓储量为】:3  
【现仓储量为】:3  
【现仓储量为】:15  
【现仓储量为】:1  
【现仓储量为】:0  
【现仓储量为】:1  
【现仓储量为】:1  
【现仓储量为】:1  
【现仓储量为】:2  
【现仓储量为】:3  
【现仓储量为】:4  
【现仓储量为】:0  
【现仓储量为】:1  
【现仓储量为】:5  
【现仓储量为】:6  
【现仓储量为】:7  
【现仓储量为】:8  
【现仓储量为】:9  
【现仓储量为】:10  
【现仓储量为】:11  
【现仓储量为】:12  
【现仓储量为】:13  
【现仓储量为】:14  
【现仓储量为】:15  
【现仓储量为】:16  
【现仓储量为】:17  
【现仓储量为】:1  
【现仓储量为】:1  
【现仓储量为】:2  
【现仓储量为】:3  
【现仓储量为】:4  
【现仓储量为】:5  
【现仓储量为】:6  
【现仓储量为】:3  
【现仓储量为】:3  
【现仓储量为】:1  
【现仓储量为】:2  
【现仓储量为】:3  
【现仓储量为】:4  
【现仓储量为】:5  
【现仓储量为】:6  
【现仓储量为】:7  
【现仓储量为】:8  
【现仓储量为】:9  
【现仓储量为】:10  
【现仓储量为】:11  
【现仓储量为】:12  
【现仓储量为】:13  
【现仓储量为】:14  
【现仓储量为】:15  
【现仓储量为】:16  
【现仓储量为】:17  
【现仓储量为】:18  
【现仓储量为】:19  
【现仓储量为】:6  
【现仓储量为】:7  
【现仓储量为】:8  
【现仓储量为】:9  
【现仓储量为】:10  
【现仓储量为】:11  
【现仓储量为】:12  
【现仓储量为】:13  
【现仓储量为】:14  
【现仓储量为】:15  
【现仓储量为】:16  
【现仓储量为】:17  
【现仓储量为】:18  
【现仓储量为】:19  
【现仓储量为】:20  
【现仓储量为】:21  
【现仓储量为】:22  
【现仓储量为】:23  
【现仓储量为】:24  
【现仓储量为】:25  
【现仓储量为】:26  
【现仓储量为】:27  
【现仓储量为】:28  
【现仓储量为】:29  
【现仓储量为】:30  
【现仓储量为】:31  
【现仓储量为】:32  
【现仓储量为】:33  
【现仓储量为】:34  
【现仓储量为】:35  
【现仓储量为】:36  
【现仓储量为】:37  
【现仓储量为】:38  
【现仓储量为】:39  
【现仓储量为】:40  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值