多线程

1.线程和进程的区别和联系
 进程的概念:进程是表示资源分配的基本单位,又是CPU调度运行的基本单位。
 线程的概念:线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。
 联系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
(5)线程属于进程,不能独立执行。每个进程至少要有一个线程,成为主线程
区别:
(1)进程是系统进行资源分配的基本单位,有独立的内存地址空间; 线程是CPU调度的基本单位,没有单独地址空间,有独立的栈,局部变量,寄存器, 程序计数器等。
(2)创建进程的开销大,包括创建虚拟地址空间等需要大量系统资源; 创建线程开销小,基本上只有一个内核对象和一个堆栈。
(3)一个进程无法直接访问另一个进程的资源;同一进程内的多个线程共享进程的资源。
(4)进程切换开销大,线程切换开销小;进程间通信开销大,线程间通信开销小。
2.创建线程的方法
(1)继承Thread类

public class ExtendsThread extends Thread {
    @Override
    public void run() {
        System.out.println(“继承Thread类实现线程");
    }
}

(2)实现Runnable接口

public class RunnableThread implements Runnable {
  @Override
    public void run() {
        System.out.println("实现Runnable接口实现线程");
    }

(3)匿名内部类

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}).start();

(4)有返回值的Callable创建线程

//实现Callable返回值类型为Integer类型
     class ImplCallable implements Callable<Integer> {
        //该call()方法将作为线程执行体,并且有返回值
        @Override
        public Integer call() throws Exception {
            //do something
            System.out.println("实现Callable接口创建线程,返回类型为Integer类型");
            return 0;
        }
    }
    public class Demo {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            Callable<Integer> callable = new ImplCallable();
            FutureTask<Integer> futureTask = new FutureTask<>(callable);
            Thread thread = new Thread(futureTask);
            thread.start();
            //获取返回值futureTask.get()
            System.out.println(futureTask.get());
        }
    }

3.线程的状态以及相互转换
这6个状态分别是:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED.
(1)NEW:这个状态呢,就是线程对象创建之后、启动之前,就是这个状态。
(2)RUNNABLE: 运行状态,当调用start方法后呢,线程就会进入RUNNABLE状态,表示,我这个线程可以被执行了,如果调度器给这个线程分配了CPU时间,那么这个线程就可以被执行,这里一定要正确区分一下RUNNABLE不是说正在执行,而是可以被执行,这两个还是有区别的。
(3)BLOCKED: 阻塞状态,表示线程阻塞于锁
(4) WAITING: 等待状态,当你调用了wait,join方法后,就会进入这个状态。一旦进入到这个状态,CPU就不会管你了,直到有别的线程通过notify方法将它唤起,否则的话,就会一直在等待中。
(5)TIMED_WAITING: 超时等待状态,有一个计时器在里面,最常见的是使用Thread.sleep方法触发,触发后,线程就进入了TIMED_WAITING状态,随后会由计时器触发,再进入RUNNABLE状态。
(6)TERMINATED 终止状态,当线程的所有代码都被执行完毕后,会进入到这个状态。
相互转换:
线程创建之后调用start()方法开始运行,当调用wait(),join(),LockSupport.lock()方法线程会进入到WAITING状态,而同样的wait(long timeout),sleep(long),join(long),LockSupport.parkNanos(),LockSupport.parkUtil()增加了超时等待的功能,也就是调用这些方法后线程会进入TIMED_WAITING状态,当超时等待时间到达后,线程会切换到Runable的状态,另外当WAITING和TIMED _WAITING状态时可以通过Object.notify(),Object.notifyAll()方法使线程转换到Runable状态。
当线程出现资源竞争时,即等待获取锁的时候,线程会进入到BLOCKED阻塞状态,当线程获取锁时,线程进入到Runable状态。线程运行结束后,线程进入到TERMINATED状态,状态转换可以说是线程的生命周期。另外需要注意的是:
当线程进入到synchronized方法或者synchronized代码块时,线程切换到的是BLOCKED状态,而使用java.util.concurrent.locks下lock进行加锁的时候线程切换的是WAITING或者TIMED_WAITING状态,因为lock会调用LockSupport的方法。
4.线程中常用的方法
(1)start()与run()
start() 启动线程并执行相应的run()方法
run() 子线程要执行的代码放入run()方法
(2)getName()和setName()
getName() 获取此线程的名字
setName() 设置此线程的名字
(3)isAlive()
是判断当前线程是否处于活动状态。活动状态就是已经启动尚未终止。
(4)currentThread()
返回代码段正在被哪个线程调用
(5)sleep()
主要的作用是让当前线程停止执行,把cpu让给其他线程执行,但不会释放对象锁和监控的状态,到了指定时间后线程又会自动恢复运行状态
注意:线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行
(6)getPriority()和setPriority(int newPriority)
这两个方法是用于获取当前和设置线程的优先级。优先级高的线程得到的cpu多。也就是说,两个等待的线程,优先级高的线程容易被cpu执行。
默认情况下,线程的优先级是5。线程的优先级分为1~10等级。
(7)getId()
取得线程唯一标识
(8)yield()
yield() 暂停当前方法,释放自己拥有的CPU,线程进入就绪状态。
(9)join()
join()方法可以使得一个线程加入主线程,当这个线程结束后,主线程才会继续往下运行。
(10)interrupted()
interrupted()是静态方法:内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态
isInterrupted()是实例方法,是调用该方法的对象所表示的那个线程的isInterrupted(),不会重置当前线程的中断状态,它们的作用是判断线程是否是停止状态
(11)setDaemon()守护线程
设置守护线程:

NewThread daemonThread = new NewThread();
daemonThread.setDaemon(true);
daemonThread.start();

需要注意的:调用 setDaemon() 方法的时机,该方法只能在创建 Thread 对象并且在启动线程前调用。在线程运行时尝试调用setDaemon() 将抛出 IllegalThreadStateException 异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值