Java多线程系列-一些区别的例子

进程和线程之间的区别

经典问题: 进程和线程到底有那些区别。

可以总结为以下几点:

  • 一个进程可以拥有多个线程,而线程不可以拥有多个进程。
  • 每个进程都拥有自己的内存空间,可执行代码和唯一进程标识符(PID).每个线程都拥有它的栈内存,但它与其他的线程共享当前进程的主内存。
  • 线程也称为任务或者轻量级进程。
  • 创建线程和创建进程也有很大的区别,创建线程就简单的new一个即可,创建进程的话需要通过对父进程的复制来实现。
  • 来自同一线程的进程可以通过使用java编程语言中的wait()和notify()等来进行通信,比进程之间的通信要简单很多。
  • 作为同一进程下的多个线程,可以共享系统资源(如文件描述符,堆内存等),但是在java中,每个线程都拥有自己的栈内存和异常处理程序(所以一个线程抛出异常,不会影响其他线程,具体过程可以自己写程序查jvisualvm)。

wait(),sleep()和yield()之间的区别

  • 第一点不同,wait()是Object类自带的方法,而sleep()和yield()是Thread类定义的方法。
  • 首先来谈wait()和sleep()的区别,wait是用于进程通信的,如果一个线程使用了wait(),那么该线程会释放所拥有的锁和监视器并加入等待队列,其他线程继续争抢锁的所有权。而sleep()是不会释放当前线程所占有的锁和监视器的,该线程只会进行一段时间的暂停
    后继续运作。
  • 而对于yield(),它只是释放了当前线程所占有的CPU,以便给另外的线程提供一个运行的机会,但不保证谁将获得CPU。它完全依赖于线程调度程序,调用yield()方法的线程甚至可能再次获得CPU。sleep()也是释放占有的CPU(当前正在执行的线程停止执行并放弃CPU以允许线程调度程序将CPU分配给另一个线程或相同的线程),一般来说,sleep()比yield()更加可靠,应该尽量选择sleep()而不是选择yield()。还有就是sleep()可以被打断,但是yield不可以。

如何检查某个线程持有特定对象的锁

  • 在Thread中,静态方法holdsLock即可完成该功能。例子如下:
public class HoldLockTest {

    @Test
    public void test() throws InterruptedException {
        final Object o=new Object();
        new Thread(()->{
            synchronized (o){
                System.out.println(Thread.currentThread().getName()+" holdLock: "+Thread.holdsLock(o));
            }
        } ).start();

      
        synchronized (o){
            System.out.println(Thread.currentThread().getName()+" holdLock: "+Thread.holdsLock(o));
        }

        System.out.println(Thread.currentThread().getName()+" holdLock: "+Thread.holdsLock(o));

    }
/*
main holdLock: true
main holdLock: false
Thread-0 holdLock: true
*/
}

posted on 2018-10-12 18:19  小新动感光波  阅读(147)  评论(0编辑  收藏  举报

导航