`

java多线程及线程池小结

    博客分类:
  • j2se
阅读更多
最近在学习线程池的东西,前面有篇文章《线程池的设计原则》,当然大多都是参考别人的思想。然后发现自己多线程真的写的太少了。现在来补充基础知识咯。。。 

wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行.

以上是jdk api的说明,对照说明写个测试:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public class Test extends Thread {

    @Override
    
public void run() {
        System.out.println("before wait!");
        
try {
            
synchronized (this) {
                
this.wait();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
try {
            Thread.sleep(20000);
        } catch (Exception e) {
            System.out.println("interrupted!");
        }
        System.out.println("after wait!");
    }

    
public synchronized void weakup() {
        
this.notify();
    }
}

public class Main {

    
public static void main(String[] args) {
        Test test = new Test();
        test.start();
        System.out.println("shit");
        
try {
            Thread.sleep(2000);
        } catch (Exception e) {
        }
        test.weakup();
        
try {
            Thread.sleep(2000);
        } catch (Exception e) {
        }
        test.interrupt();
        System.out.println("shit");
    }
wait和notify针对的是对象,而不是线程。因为这两个方法都是Object的方法。与线程无关。
所有的线程结束之后,程序才会结束。此处如果不sleep的话,有可能weakup会早于wait先调用。
执行interrupt()时,并不需要获取Thread实例的锁定.任何线程在任何时刻,都可以调用其他线程interrupt().当sleep中的线程被调用interrupt()时,就会放弃暂停的状态.并抛出InterruptedException.
interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。 
如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。 
线程A在执行sleep,wait,join时,线程B调用A的interrupt方法,的确这一个时候A会有InterruptedException异常抛出来.但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。 
如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,都不会去检查中断状态,所以线程A不会抛出InterruptedException,而会一直执行着自己的操作.当线程A终于执行到wait(),sleep(),join()时,才马上会抛出InterruptedException. 
若没有调用sleep(),wait(),join()这些方法,或是没有在线程里自己检查中断状态自己抛出InterruptedException的话,那
InterruptedException是不会被抛出来的. 
下面再看tomcat的线程池就比较清楚了:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->class ControlRunnable implements Runnable {
        ThreadPool p;
        Thread t;
        ThreadPoolRunnable toRun;
        
boolean shouldTerminate;
        
boolean shouldRun;
        
boolean noThData;
        Object thData[] = null;

        ControlRunnable(ThreadPool p) {
            toRun = null;
            shouldTerminate = false;
            shouldRun = false;
            
this.p = p;
            t = new Thread(this);
            t.start();
            noThData = true;
            thData = null;
        }

        
public void run() {
            
while (true) {
                
try {
                    
synchronized (this) {
                        
if (!shouldRun && !shouldTerminate) {
                            
this.wait();
                        }
                    }
                    
if (shouldTerminate) {
                        
break;
                    }
                    
try {
                        
if (noThData) {
                            thData = toRun.getInitData();
                            noThData = false;
                        }
                        
if (shouldRun) {
                            toRun.runIt(thData);
                        }
                    } catch (Throwable t) {
                        System.err.println("ControlRunnable Throwable: ");
                        t.printStackTrace();
                        shouldTerminate = true;
                        shouldRun = false;
                        p.notifyThreadEnd();
                    } finally {
                        
if (shouldRun) {
                            shouldRun = false;
                            p.returnController(this);
                        }
                    }
                    
if (shouldTerminate) {
                        
break;
                    }
                } catch (InterruptedException ie) {
                }
            }
        }

        
public synchronized void runIt(ThreadPoolRunnable toRun) {
            
if (toRun == null) {
                
throw new NullPointerException("No Runnable");
            }
            
this.toRun = toRun;
            shouldRun = true;
            
this.notify();
        }

        
public synchronized void terminate() {
            shouldTerminate = true;
            
this.notify();
        }
ControlRunnable线程类是线程池中的具体线程,线程构造函数中调用线程的start开始线程,到run方法里得到自己的锁然后wait,等待具体的动作调用:runIt,动作调用就可以notify线程了。里边将线程要做的具体工作委托给了ThreadPoolRunnable接口,用户要使用线程池,只用将自己的任务实现此接口即可。ThreadPoolRunnable的代码如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public interface ThreadPoolRunnable {
    
public Object[] getInitData();
    
        
public void runIt(Object thData[]);
}
另外,ThreadPool本身还运行了一个MonitorRunnable的线程,用来管理线程池。当(currentThreadCount - currentThreadsBusy) > maxSpareThreads,就会调用ControlRunnable类的terminate方法删除空闲线程,准备删除的线程是否空闲是通过shouldTerminate参数来判断。线程池采用Vector来存储当前空闲的线程。

接下来回去研究java nio包。网络编程也是自己一直都想去系统的学习的东西。而且,在java nio中有很多和多线程相通的地方。比如非阻塞和多线程,当然,他们不是一个意思。
分享到:
评论

相关推荐

    Java多线程小结

    ### Java多线程小结 #### 一、多线程的概念与意义 多线程是Java编程中的一个重要概念,指的是程序在运行时可以同时执行多个线程的能力。它能够提高程序的性能,尤其是在多核处理器的环境下。多线程使得程序能够更...

    java线程池封装j

    Java线程池是一种高效管理线程的技术,它允许开发者预定义一组线程,根据任务的需要灵活调度,而不是每次需要执行任务时都创建新的线程。这种设计模式大大提高了系统的性能,减少了系统资源的消耗,特别是在高并发...

    java多线程设计模式

    ### Java多线程设计模式详解 #### 一、Java多线程基础 Java语言自诞生以来,便内置了对多线程的支持。多线程能够让程序在同一时间处理多个任务,提高程序的执行效率和响应速度。Java中创建线程有两种基本方式: 1...

    java线程详解

    八、线程同步小结 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:volatile关键字 Java线程:新特征-线程池 一、固定大小的线程池 二、单任务线程池 三、可变尺寸的线程池 四、延迟连接池 五、...

    Java线程类小结(附思维导图)

    - **线程安全的集合类**:如`ConcurrentHashMap`、`CopyOnWriteArrayList`等,设计用于多线程环境。 - **原子类(Atomic*)**:如`AtomicInteger`、`AtomicLong`,提供原子操作,常用于实现无锁编程。 7. **线程...

    突破JAVA万人面试,懂多线程者得天下.zip

    目录网盘文件永久链接 01课程安排av 02什么是并发和并行av ...08线程创建小结av 09线程生命周期avi 10.线程安全问题什么是线程安全avi 11线程安全同题问题分析avi 12线程安全问题线程安全问题演示avi ...............

    Android异步加载图像小结 (含线程池,缓存方法).zip

    在实际项目中,"Android异步加载图像小结 (含线程池,缓存方法).doc"文档可能详细介绍了这些技术的实现细节和案例,而"项目说明.zip"可能包含了具体实现的代码示例,供开发者参考学习。 总的来说,高效地在...

    Android异步加载图像小结 (含线程池,缓存方法).rar

    在Android应用开发中,图像加载是一个常见的...以上就是关于“Android异步加载图像小结(含线程池,缓存方法)”的主要知识点。在实际应用中,开发者应结合项目需求,合理选择和优化这些技术,以提供流畅的用户体验。

    Android异步加载图像小结 (含线程池,缓存方法).doc.zip

    - 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。在Android中,可以使用Java的ExecutorService和ThreadPoolExecutor来创建线程池,控制并发量,防止过度创建线程...

    基于Android的Android异步加载图像小结 (含线程池,缓存方法).zip

    线程池可以高效地管理和调度多个线程,避免频繁创建销毁线程带来的开销。 2. **Java并发库中的ExecutorService**:Java提供了`ExecutorService`接口,它是线程池的实现。我们可以使用`Executors`类提供的工厂方法来...

    Android--开发--异步加载图像小结 (含线程池,缓存方法).rar

    线程池是多线程编程中的一个优秀实践,它通过预先创建并维护一定数量的工作线程来避免频繁创建和销毁线程带来的开销。在Android中,我们可以使用`java.util.concurrent`包下的`ExecutorService`接口及其实现类来创建...

Global site tag (gtag.js) - Google Analytics