黑马程序员-多线程

来源:互联网 发布:上海微创软件待遇 编辑:程序博客网 时间:2024/05/16 00:40
------- android培训、java培训、期待与您交流! ----------

进程:是一个正在执行的程序。

             每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行。

一个进程中至少有一个线程。

 

Java虚拟机启动的时候会有一个进程java.exe,该进程中至少一个线程负责java程序的执行。

而且这个线程运行的代码存在于main方法中,该线程成为主线程。

更细节的说明jvmjvm启动不止一个线程,还有负责垃圾回收机制的线程。

 

创建线程:

第一种方式,继承Thread

1.      定义类继承Thread

2.      复写Thread类中的run()方法

目的:将自定义代码存储在run方法中,让线程运行

3.      调用线程的start()方法,该方法有两个作用:启动线程,调用run方法。

class demo extends Thread

{

       publicvoid run()

       {

 

}

}

 

多线程的一个特性:随机性,那个线程抢到cpu执行权,哪个就先执行。

 

线程都有自己默认的名称,通过getName()方法获取,名称是Thread-编号,该编号从0开始。

 

Thread类的方法:

构造方法设置线程名称:Thread(Stringname),子类直接调用就可以,

classTest extends Thread

{

       Test(Stringname)

       {

              super(name);

}

public voidrun()

{

       System.out.println(Thread.currentThread().getName());

}

}

class demo{

       publicstatic void main(String []args){

              Ttestt1 = new Test(“one”);

              Testt2 = new Test(“two”);

              t1.start();

              t2.start();

       }

}

getName()获取线程名称

currentThread()返回当前线程对象,static Thread      Thread.currenThread()

 

第二种方式:实现Runnable接口

1.      定义类实现Runnnable接口

2.      覆盖Runnnable接口中的run方法

3.      通过Thread类建立线程对象

4.      将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数

自定义的run方法所属的对象是Runnable接口的子类对象,要让线程去指定指定对象的run方法,就必须明确该run方法所属对象

5.      调用Thread类的start方法启动线程并调用Runnable接口子类的run方法

class Test implements Runnable

{

       publicvoid run()

       {

              System.out.println();

}

}

class demo

{

       publicstatic void main()

       {

              Testt = new Test();

              Threadt1 = new Thread(t);

              Threadt2 = new Thread(t);

              t1.start();

              t2.start();

}

}

 

实现方式和继承方式的区别:

实现方式好处:避免了单继承的局限性。

在定义线程时,建议使用实现方式。

 

 

 

class Test implements Runnable

{

       privateint ticket = 100;

       publicvoid run()

       {

              while(true)

              {

                     if(ticket>0)                   //这里会出现安全问题

                     {

                            try{Thread.sleep(10);}catch(Exceptione){}

                            System.out.println(currentThread().getName()+”….”+ticket--);

}

}

}

}

class demo

{

       publicstatic void main()

       {

              Testt = new Test();

              Threadt1 = new Thread(t);

              Threadt2 = new Thread(t);

              Threadt3 = new Thread(t);

              Threadt4 = new Thread(t);

              t1.start();

              t2.start();

              t3.start();

              t4.start();

}

}

多线程的运行出现安全问题:

问题原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

 

解决:同步代码块

synchronized(对象)

{

       需要被同步的代码

}

对象如同锁,持有锁的线程可以在同步中执行。

没有持有锁得线程即使获得cpu的执行权,也进不去,因为没有获取锁

 

前提:必须是多个线程使用同一个锁

        必须要有两个或两个以上的线程

 

 

 

Object obj = new Object();

synchronized(obj)

{

if(ticket>0)                   

                     {

                            try{Thread.sleep(10);}catch(Exceptione){}

                            System.out.println(currentThread().getName()+”….”+ticket--);

}

}

 

同步有两种表现形式,一种是同步代码块,一种是同步函数

比如:publicsynchronized void add(int n)

              {

                     Sum= sum+n;

                     System.out.println(sum);

}

 

同步函数用的锁:

       函数需要被对象调用,那么函数都有一个所属对象引用,this,所以同步函数使用的锁就是this

 

静态同步方法使用的锁是该方法所在类的字节码文件对象。 类名.class

 

懒汉式

class Single

{

       privatestatic Single = null;

       privateSingle(){}

       publicstatic void getInstance()

       {

              if(s==null)

              {

                     synchronized(Single.class)

                     {

                            If(s==null)

                            {

                                   s = new Single();

}

                     }

}

return s;

}

}

死锁:同步中嵌套同步

class Test implements Runnable

{

       privateboolean flag;

       Test(booleanflag)

       {

              this.flag= flag;

}

       publicvoid run()

       {

              if(flag)

              {

                     synchronized(Mylock.locka)

                     {

                            System.out.println("iflocka");

                            synchronized(Mylock.lockb)

                            {

                                   System.out.println("iflockb");

                            }

                     }

              }

              else

              {

                     synchronized(Mylock.lockb)

                     {

                            System.out.println("elselockb");

                            synchronized(Mylock.locka)

                            {

                                   System.out.println("elselocka");

                            }

                     }

              }

       }

}

class Mylock

{

       staticObject locka = new Object();

       staticObject lockb = new Object();

}

class sisuo{

       publicstatic void main(String []args){

              Threadt1 = new Thread(new Test(true));

              Threadt2 = new Thread(new Test(false));

              t1.start();

              t2.start();

       }

}

原创粉丝点击