Java之路--Javase篇 多线程(1)

         在所谓的大公司混了一年,发现在这个圈子,如果你的可替代性太高。不是被忽视就是被忽视,故为钱途计、为前途计,痛定思痛。一头扎进java的怀抱。这条路正所谓:钱途是光明的,道路是曲折的,努力是必须的。那么让我从今天起逐步开启java的大门。

下面是我今天的学习内容:

                                                     

                                多线程

1.线程的创建

线程:实际就是code的执行路径。

线程的创建有下面两种方法:

extdens  Thread类并重写run方法;

implement  Runable 接口并实现run方法。

注意:run中的代码就是新线程会执行的code。

2.run和start的区别:run---是对方法的普通调用,整个过程中只有一个线程,效率较低;start---是开启一个新的进程(执行路径)达到多线程同时执行的效果,加快效率。

3.线程名称

  主线程名称就为main

  其他线程名称为 Thread-编号(从0开始编号)

通过使用Thread.currentThread().getName()获取当前线程的名称。其中Thread.currentThread()获取当前线程对象。

4.线程的状态:

  

 

5. Thread类子类run方法和Runnable接口run方法都存在时:执行Thread类子类中的run方法。 

6.创建Thread子类和实现Runnable接口中对资源处理的差异:

  Create Thread的子类---将资源封装于每个子类中,每建立一个子类就会自带一个资源而不能达到资源共享之目的;

  Implement Runnable---将资源封装于Runnable中,每个线程连接此资源完成共享。

 类似代码:

  

public class SaleTicket {

  

/**

 * 我也来卖卖票ticket

 */

public static void main(String[] args) {

/**   Thread a = new Thread(new Sale());

  Thread b = new Thread(new Sale()); //类似于建立Thread子类

  Thread c = new Thread(new Sale());

*/

 Sale m = new Sale();

     Thread a = new Thread(m);

     Thread b = new Thread(m);

     Thread c = new Thread(m);

  a.start();

  b.start();

  c.start();

}

}

class Sale implements Runnable{

private int t = 100;

public void run(){

while(true){

if(t >0){  //cpu被不断切换,导致第二轮线程进入时不再判断前面前提导致出错

System.out.println(Thread.currentThread().getName()+"卖出的第"t-- +"张票");

}

}

}

}

                   

7.多线程安全问题:

原因---四个线程同时处理共享数据票数据,A线程对操作语句中的一部分执行完,没有执行剩下的语句,就被B线程抢走Cpu执行权,B执行后将数据改变,但是A线程在再次执行时不再判断前提条件,就直接接着上次流程处理。导致数据出错。

解决方案---在一个时间段,对于多条操作共享资源的语句,必须由一个线程处理完成,而在其中途其他线程不能参与其中。也就是同步(synchronized)。

同步代码块格式:

Synchronized(唯一对象){

同步代码

}

8.Synchronized的弊端:执行效率降低;

synchronized的好处:解决多线程情况下共享数据出错问题

synchronized的使用前提:多线程,至少2个及以上;多个线程必须使用同一个“锁”;

9.当一个函数中所有的代码都被synchronized同步后,则可以直接将这个函数直接用synchronized修饰。称之为同步函数。可以将同步代码块转换称同步函数:将同步代码块中的code提出来单独封装成一个函数,然后去调用它。

10.同步函数的锁是用的this锁;static同步函数使用的是本身字节码对象作锁。(静态随着类的加载而加载,静态存在之前先有类,类进内存需要先加载class(字节码文件)文件,字节码进内存前先封装成对象,用“类名.class”表示。)

11.同步函数和同步代码块的区别:(开发中使用同步代码块好些)

同步函数书写简单,同步函数使用的锁是this或者字节码对象。

同步代码块书写需要多一层缩进,同步代码块使用的锁是使用的锁是固定的。

12.线程间通讯

   启动多个线程对同一个资源进行操作;且每个线程对资源的操作方式都不一样(比如一个在添加另一个在删除);每一个线程都有自己的run方法,所以每个run方法都要封装到不同的类中

13.线程死锁

   线程的死锁最常见于同步的嵌套中;表现为程序暂停,而不运行,但是线程并未消亡;A锁同步中有B锁,而B锁的同步中有A锁。(开发时一定要避免死锁的情况,尽量避免同步嵌套)

15.lock和unlock 

JDK1.5之后java提供了更新的锁操作。

在java.util.concurent.locks包中提供了新的对象Lock接口。此对象的产生替换了synchronized同步。

其优势:synchronized对锁操作是隐式的,获取锁和释放锁都是隐式的,只要线程执行到同步语句就获取到锁,执行完同步语句,就释放锁,用起来并不明显。

     而Lock的出现,是按照面向对象的思想将锁操作封装成对象。并提供了对锁的显示操作。lock():获取锁;unlock():释放锁。

     操作监视器的方法wait notify notifyAll都需要关联自己所属的同步锁。有了新的锁对象后,应该匹配和这个新的锁对象关联的操作监视器的方法。Jdk1.5后,在java.util.concurent.locks包中提供了一个Condition对象,用它来替代了Object,并提供了替代wait notify notifyAll的方法。

Wait --àawait();

Notify-àsignal();

notifyAll-àsingnalAll();

并将这些操作监视器的方法封装到了Condition对象中。

Lock出现的好处就在于一个Lock锁对象上可以关联多个监视器对象。达到分别管理,针对性wait和signal的好处。

Lock的分析和详解:

 

 

欲知后事如何,且听下会分解!

  

 

 

                                        

你可能感兴趣的:(java,公司,前途,休闲,光明)