Java多线程(上)

来源:互联网 发布:sm4密码算法.pdf 编辑:程序博客网 时间:2024/06/15 16:15

创建线程

1.        第一种方式:继承Thread类

步骤:

1)        定义一个类继承Thread

2)        覆写Thread类中的run()方法

3)        调用线程的start()方法——启动线程,调用run()方法

 

程序示例:

class Demoextends Thread

{

         public void run()

         {

                   for(int i = 0; i < 100;i++)

                            System.out.println("Thread run---- "+ i);

         }

}

public classThreadDemo

{

         public static void main(String[] args)

         {

                   Demo d = new Demo();

            d.start();

                   for(int i = 0; i < 100;i++)

                            System.out.println("java thread----"+ i);

         }

}

 

线程都有自己默认的名称,Tread-编号,该编号从0开始。

我们可以自己设置线程名称,staticThread currentThread():获取当前线程对象,

getName():获取线程名称,通过setName()或者构造函数super()进行设置。

class MyThreadextends Thread

{

         //private String name;

         MyThread(String name)

         {

                   //this.name = name;

                   super(name);

         }

         public void run()

         {

                   for(int x = 0; x <50; x++)

                   {

                            System.out.println(Thread.currentThread().name+ " run..." + x);

                            //System.out.println(this.getName()+ " run..." + x);

                   }

         }

}

class ThreadTest

{

         public static void main(String[] args)

         {

                   MyThread t01 = newMyThread("one");

                   MyThread t02 = newMyThread("two");

                   t01.start();

                   t02.start();

                   for(int x = 0; x < 50;x++)

                   {

                            System.out.println("mainrun..." + x);

                   }

         }

}

 

2.        创建线程的第二种方法:

 

1)        实现Runnable接口,

2)        覆盖它的run(),run()中存放线程要执行的代码

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

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

         让线程执行指定对象的run()方法

5)        调用Thread类的start()方法开启线程

 

两种创建线程的方法(extendsThread 和 implements Runnable)的区别:

实现方式的好处:打破了java单继承的局限性。

 

程序示例:

class Ticketimplements Runnable

{

         private int ticket = 100;//static 一般不用,因为它的生命周期太长

         /*

         public void setName(String name)

         {

                   this.name = name;

         }

         public String getName()

         {

                   return name;

         }

         */

 

         /*

          *Ticket(String name)

          *{

          *     super(name);

          *}

          */

 

         public void run()

         {

                   while(true)

                   {

                            if(ticket > 0)

                            {

                                     System.out.println(Thread.currentThread().getName()+ "...sale : " + ticket--);                     

}

                   }

         }

}

class TicketTest

{

         public static void main(String[] args)

         {

                   Ticket ticket = new Ticket();

 

                   //让线程执行指定对象(此处为ticket)的run()方法

                   Thread t1 = newThread(ticket, "t1");

                   Thread t2 = newThread(ticket, "t2");

                   Thread t3 = newThread(ticket, "t3");

 

                   t1.start();

                   t2.start();

                   t3.start();

         }

}

同步

多线程的运行存在安全问题

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

解决方法:

对共享数据的多条操作语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。即同步。

同步的前提:

1)        必须有两个或者两个以上线程

2)        多个线程共用一个锁

同步好处:

         解决了多线程安全问题。

同步弊端:

         多个线程需要判断锁,较为消耗资源。

 

1.        同步代码块

synchronized(Object)

{

         需要被同步的代码(操作共享数据的代码)

}

对象如同锁,比如火车的卫生间门上的提示。

 

程序示例:

classTicket implements Runnable//extends Thread

{

         private int ticket = 100;

         Object obj = new Object();

 

         public void run()

         {

                   while(true)

                   {

                            synchronized(obj)//同步代码块

                            {

                                     if(ticket> 0)

                                     {

                                               try

                                               {

                                                        Thread.sleep(10);

                                               }

                                               catch(Exception e)

                                               {

                                               }

                                               System.out.println(Thread.currentThread().getName()+ "...sale : " + ticket--);

                                     }

                            }

                   }

         }

}

 

publicclass TicketTest02

{

         public static void main(String[] args)

         {

                   Ticket ticket = new Ticket();

                  

                   Thread t1 = newThread(ticket, "t1");

                   Thread t2 = newThread(ticket, "t2");

                   Thread t3 = newThread(ticket, "t3");

 

                   t1.start();

                   t2.start();

                   t3.start();

         }

}

 

2.        同步函数

同步函数用的锁是 this

 

程序示例:

需求:某银行有一个金库,两个储户分别存300元,每次存100,存三次

classBank

{

         private int sum;//成员变量可以不初始化,默认是0

 

         public synchronized void add(intmoney)//使用synchronized修饰的同步函数

         {

                   sum += money;

                   try

                   {

                                              Thread.sleep(10);

                                     }

                   catch (Exception e)

                   {

                   }

                   System.out.println("sum= " + sum);

         }

}

 

classChest implements Runnable//金库类

{

         private Bank bank = new Bank();

         public void run()

         {

                   for(int x = 0; x < 3; x++)   

                   {

                            bank.add(100);//存入100,存三次

                   }

         }

}

publicclass BankDemo

{

         public static void main(String[] args)

         {

                   Chest c = new Chest();

 

                   //创建两个线程,即两个储户

                   Thread t1 = new Thread(c)

                   Thread t2 = new Thread(c);

 

                   t1.start();

                   t2.start();

         }

}

3.        静态同步函数使用的锁是:类名.class (不再是this 静态方法中不可以定义this)

静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,类名.class。该对象的类型是Class

 

         程序示例:

class Ticket implements Runnable

{

         privatestatic int ticket = 1000;

         booleanflag = true;

         publicvoid run()

         {

                   if(flag)

                   {

                            while(true)

                            {

                                     synchronized(Ticket.class)//同步代码块

                                     {

                                               if(0< ticket)

                                               {

                                                        try

                                                        {

                                                                 Thread.sleep(10);

                                                        }

                                                        catch(Exception e)

                                                        {

                                                        }

                                                        System.out.println(Thread.currentThread().getName()+ "....code....." + ticket--);

                                               }

                                     }

                            }

                   }

                   else

                   {

                            while(true)

                            {

                                     show();

                            }

                   }

         }

         publicstatic synchronized void show()//静态同步函数

         {

                   if(0< ticket)

                   {

                            try

                            {

                                     Thread.sleep(10);

                            }

                            catch(Exception e)

                            {

                            }

                            System.out.println(Thread.currentThread().getName()+ ".....show..... " + ticket--);

                   }

         }

}

public class StaticSynchronized

{

         publicstatic void main(String[] args)

         {

                   Tickettick = new Ticket();

                   Threadt1 = new Thread(tick, "thrEAd01");

                   Threadt2 = new Thread(tick, "thrEAd02");

                   Threadt3 = new Thread(tick, "thrEAd03");

 

                   t1.start();                  

                   try

                   {

                            Thread.sleep(40);

                   }

                   catch(Exception e)

                   {

                   }

                   t3.start();

                   try

                   {

                            Thread.sleep(40);

                   }

                   catch(Exception e)

                   {

                   }

                   tick.flag= false;       

                   t2.start();

         }

}


原创粉丝点击