Java多线程基础知识疑难点

最简单Java程序包含有哪些线程?

代码为证:

/**
 * Created by Genge on 2016-06-07.
 */
public class MultiThread {
    public static void main(String[] args) {
        ThreadInfo[] threadInfos = ManagementFactory.getThreadMXBean().dumpAllThreads(false, false);
        for (ThreadInfo threadInfo : threadInfos){
            System.out.println("[" + threadInfo.getThreadId() + "]" + threadInfo.getThreadName());
        }

    }
}

效果图:

[10]Monitor Ctrl-Break
[5]Attach Listener       //添加事件
[4]Signal Dispatcher    // 分发处理给JVM信号的线程
[3]Finalizer           //调用对象finalize方法的线程
[2]Reference Handler   //清楚reference线程
[1]main   //main线程,程序入口

Process finished with exit code 0

可以看到一个Java程序的运行不仅仅是main()的方法的运行,而是多线程同时运行!

Thread.yield()误用?

  • Yield是一个静态的原生(native)方法
  • Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。
  • Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态
  • 它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态

总结:

Thread.yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会,从而公平竞争。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

线程优先级Priority参数靠谱吗?

一点都不靠谱,建议不要用了,忘了他。虽然线程优先级就是决定线程需要多或者少分配一些处理器资源的线程属性,但是priority的实现太过于依赖具体操作系统。因此线程优先级不能作为程序正确性的依赖!

Daemon线程会导致finally不能执行?

当一个Java虚拟机中不存在非Daemon线程的时候,Java虚拟机将会退出,即所有线程都要立即停止,包括Daemon线程(守护线程)。在构建Daemon线程时,不能依靠finally块中的内容来确保执行关闭或者清理资源的逻辑。另外Daemon属性需要在启动线程之前设置,不能启动线程之后设置。

线程中断状态判断?

  • 从java的api中可以看到,许多声明抛出InterruptException的方法,例如 Thread.sleep(long mills) 这些方法在抛出InterruptException之前,Java虚拟机会先将该线程的中断状态标示位清除,然后跑出InterruptException,此时调用isInterrupted()方法将会返回false.如果没有抛出异常,直接调用Interrupt(),标示位重为中断状态。
  • 另外Thread.interrupted()也会对当前线程的中断标识就行复位,虽然他是判断当前线程是否为中断状态。
  • 中断检测函数区别
 public boolean isInterrupted() {
        return isInterrupted(false);
 }
 public static boolean interrupted() {
        return currentThread().isInterrupted(true);
 }

使用模板设计模式实现独占锁同步组件

package com.genge.multithread;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * Created by Genge on 2016-06-08.
 * 独占锁同步组件实现
 */
public class Mutex implements Lock {
    // 推荐使用静态内部类 继承 队列同步器
    private static class Sync extends AbstractQueuedSynchronizer{
        protected Sync() {
            super();
        }

        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if (getState() == 0) {
                throw new IllegalMonitorStateException();
            }
            setState(0);
            return true;
        }

        @Override
        protected int tryAcquireShared(int arg) {
            return super.tryAcquireShared(arg);
        }

        @Override
        protected boolean tryReleaseShared(int arg) {
            return super.tryReleaseShared(arg);
        }
        //是否处在独占状态
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        @Override
        public String toString() {
            return super.toString();
        }
        Condition newCondition(){
            return new ConditionObject();
        }

    }

    private final Sync sync = new Sync();

    public void lock() {
        sync.acquire(1);
    }

    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(time));
    }

    public void unlock() {
        sync.release(1);
    }

    public Condition newCondition() {
        return sync.newCondition();
    }

}

AQS队列同步器独占式同步状态获取与释放过程?

在获取同步状态时,同步器维护一个同步队列,回去状态失败线程都会加入到队列中并在队列中进行自旋;移出队列(或者停止自旋)的条件是前驱节点为头节点且成功获取了同步状态。在释放同步状态时,同步器调用tryRelease(int arg)方法释放同步状态,然后唤醒头节点的后继结点。另外共享式与独占式最主要的区别在于同一时刻能否有多个线程同时获取到这个同步状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值