Java 关于线程的一些使用

Posted 瞌睡先生想睡觉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 关于线程的一些使用相关的知识,希望对你有一定的参考价值。


public class Demo 

    public static void main(String[] agr) throws Exception 
        Demo demo = new Demo();
        demo.test();
    


    //线程的wait,notify必须和synchronized一起使用
    //即,当前线程拿属于object的锁之后,就可以调用wait让此线程进入等待状态,然后抛出锁,等待其他线程那到object的锁之后唤醒
    //挂在object上的线程,如果有多个线程挂在object一个对象上那么notify只会唤醒一个线程
    public Object object = new Object();

    public void test() throws InterruptedException 

        new Thread() 
            @Override
            public void run() 
                synchronized (object) 
                    L.d("线程1进入等待状态");
                    try 
                        object.wait();
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    L.d("线程1继续运行");
                
            
        .start();

        new Thread() 
            @Override
            public void run() 
                synchronized (object) 
                    L.d("线程2进入等待状态");
                    try 
                        object.wait();
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    L.d("线程2继续运行");
                
            
        .start();
        new Thread() 
            @Override
            public void run() 
                synchronized (object) 
                    L.d("线程3进入等待状态");
                    try 
                        object.wait();
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    L.d("线程3继续运行");
                
            
        .start();

        Thread.sleep(1000);
        synchronized (object) 
            object.notify();
        
    


如果像下面这个没有拿到锁就调起wait就会抛出IllegalMonitorStateException异常

        new Thread() 
            @Override
            public void run() 
                try 
                    wait();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        .start();

或者是这样,虽然拿到了object的锁但是并没有挂起在object这个对象上就也会抛出异常

        new Thread() 
            @Override
            public void run() 
                synchronized (object)
                    try 
                        wait();
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                

            
        .start();

上面两种直接调用的wait是将自己直接挂在Thread本类这个对象上所以要进行拿到本类对象的锁才可以,像下面这样就不会抛出异常

    public void test() throws InterruptedException 
        Thread thread = new Thread() 
            @Override
            public synchronized void run() 
                L.d("线程开始");
                try 
                    wait();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
                L.d("线程完成等待");
            
        ;

        thread.start();

        Thread.sleep(1000);
        synchronized (thread) 
            thread.notify();
        
    

有关线程的状态

NEW刚刚创建的线程尚且没有运行
RUNNABLE正在运行中的线程
WAITING线程等待中
TIMED_WAITING计时等待,调用wait(long timeout)之后所处的状态
BLOCKED阻塞状态,synchronized的锁已经被其他线程拿到而没有释放,此时线程被阻塞在synchronized
TERMINATED终止状态,线程运行完成

另外如果线程调用sleep是不会释放已经拿到的synchronized锁,如果是调用wait方法则会释放已经到的synchronized锁

关于thread.join()方法的使用,如果在a线程中调用了b线程的join方法,那么a线程就会进入等待直至b线程执行完成才会继续执行,用网上的专业一点的说法就是将线程由并行转为串行,join内部调用的就是wait方法,

例子:

    public void test() 
        Thread thread1 = new Thread() 
            @Override
            public void run() 
                for (int i = 0; i < 10; i++) 

                    try 
                        Thread.sleep(1000);
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    L.d("线程1 : " + i);
                
            
        ;
        thread1.start();

        Thread thread2 = new Thread() 
            @Override
            public void run() 
                for (int i = 0; i < 10; i++) 
                    try 
                        Thread.sleep(1000);
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    L.d("线程2 : " + i);
                    try 
                        if (i == 5) 
                            thread1.join();
                        
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                
            
        ;
        thread2.start();
    

join方法的源码:

    public final synchronized void join(long millis) throws InterruptedException 
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) 
            throw new IllegalArgumentException("timeout value is negative");
        

        if (millis == 0) 
            while (isAlive()) 
                wait(0);
            
         else 
            while (isAlive()) 
                long delay = millis - now;
                if (delay <= 0) 
                    break;
                
                wait(delay);
                now = System.currentTimeMillis() - base;
            
        
    

以上是关于Java 关于线程的一些使用的主要内容,如果未能解决你的问题,请参考以下文章

java编程规范

关于Java中的synchronized关键字

Java 关于线程的一些使用

请高手帮我看下线程的错误

下面有关Java异常处理模型的说法错误的是

SQL Server 提供了一些字符串函数,以下说法中正确的是