java线程知识点

1. 进程与线程

一个进程拥有多个线程,多个线程共享进程的内存块。操作系统不分配新的内存,因此线程之间通信很容易。不同的进程因处于不同的内存块,因此进程之间通信较为困难。

 进程:每个进程都有独立的代码和数据空间(进程上下文) ,进程切换的开销大。
 线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
 多进程:在操作系统中,能同时运行多个任务程序。
 多线程:在同一应用程序中,有多个顺序流同时执行。

2.线程的执行

多线程并非多线程一起执行,而是以很快的速度切换执行,并且切换无序,执行时间也不定。在宏观上给人以同步的感受,但是微观上还是异步执行

Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之间,

缺省是5(NORM_PRIORITY)。 java中线程是抢占机制,顾名思义,谁抢到谁用!优先级高的线程有更大的机会获得 CPU 时间,优先级低的线程也不是没有机会,

只是机会要小一些罢了

3.临界资源

因为线程的执行时随机的,不受控制的,所以在多线程编程中会有线程安全问题(临界资源,此资源会被多个进程同时访问):

 如,int n ; 线程A修改 变量 n 输出,但是在还未输出时,线程B修改了n的值,这就导致A的输出结果不正确。

在银行或者售票系统中,这是完全不能接受的。在java中,采用关键字 synchronized (修饰符),使线程像营业厅的顾客一样,一个排队进行。其所修饰的方法为同步方法。

4.  synchronized

只要被synchronized修饰,该对象的所有同步方法,一次只能被访问一个。如果同时被static修饰,那么该类的所有对象一次只能同时被一个线程访问。

/***************************************理解可能偏,看其他文章****************************************************************

     访问某个对象的synchronized方法时,表示将该对象上锁,此时其他任何线程都无法再去访问该synchronized方法了,直到之前的那个线程执行方法完毕后(或者是抛出了异常),那么将该对象的锁释放掉,其他线程才有可能再去访问该synchronized方法。 

     如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其他线程是无法访问该对象的任何synchronized方法的。 

     如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的对象所对应的Class对象,因为Java中无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,他们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始执行

 synchronized块,写法: 

synchronized(object) 

表示线程在执行的时候会对object对象上锁。 

    synchronized方法是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该synchronized方法;synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内、synchronized块之外的代码是可以被多个线程同时访问到的。 

******************* ********************************************************************************+/

5.线程的生命周期

   

 创建状态: Thread th = new ThreadClass();

                当一个线程处于创建状态时,它仅仅是一个空的线程对象,系统不为他分配哦资源。

就绪状态: th.start();

                系统为这个线程分配所需资源,次线程处于课运行状态,但不是运行状态。

运行状态:

                该线程获取了cpu的调度

不可运行状态:   

                 调用sleep()方法,注意调用该方法不会打开对象锁,就是说不允许其他线程进入。

                 调用wait()方法,注意该方法相当于离开了位子,运行其他线程进入。如果该线程要再次调用,需要在队列等待。

                 调用suspend()方法。

                 输入输出流发生线程阻塞。

                 处于这一状态,即使处理器空闲也不会执行该线程。

死亡状态:

                 自然撤销,线程运行完毕。

                 stop方法,不推荐使用该方法(貌似被废除了)。

6.线程的使用

java提供两种线程,一种继成,一种接口

1.继承 Thread 类,覆盖方法 run()

2. 实现 Runnable 接口

我也一直想弄了解这两个的区别,不可能同一个东西要用两个方法。

     在使用中,应该使用那种方式呢?当然使用哪种方式都行,然而在Runnable接口API文档中已经详细地说明该如何选择这两种方式:大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类(Thread)创建子类。

 要多写代码才能理解更多。

原文地址:https://www.cnblogs.com/yuhanghzsd/p/5314871.html