1、 java 中的 多线程在 java中 要想实现多线 程,有两种手段,一种是继续 Thread 类 ,另外一种是实 现 Runable 接口。对于直接继承 Thread的类来说,代码大致框架 是:?123456789101112class 类名 extends Thread方法1 ;方法2 ;public void run()/ other code属性1 ;属性2 ;先看一个简单 的例子:?12345678910111213141/* author Rollen-Holt 继承 Thread类,直接调用 run方法* */class helloextends Thread public he
2、llo() public hello(String name) this.name = name;public void run() for (int i =0; i 0) System.out.println(“count= “ + count-);public static void main(String args) hello h1 =new hello();hello h2 =new hello();hello h3 =new hello();h1.start();h2.start();h3.start();private int count =5;12223【运行结果】:count
3、= 5count= 4count= 3count= 2count= 1count= 5count= 4count= 3count= 2count= 1count= 5count= 4count= 3count= 2count= 1大家可以想象 ,如果这个是一 个买票系统的 话,如果 count 表示的是车 票的数量的话 ,说明并没有实 现资源的共享 。我们换为 Runnable接口?123456class MyThreadimplements Runnableprivate int ticket =5; /5张票public void run() for (int i=0; i0) Syste
4、m.out.println(Thread.currentThread().getName()+“正在卖票“ +this.ticket-);public class lzwCode public static void main(String args) MyThread my =new MyThread();new Thread(my,“1号窗口“ ).start();new Thread(my,“2号窗口“ ).start();new Thread(my,“3号窗口“ ).start();【运行结果】:count= 5count= 4count= 3count= 2count= 1总结一下吧
5、:实现 Runnable 接口 比继承 Thread 类所具 有的优势:1):适合多个相同 的程序代码的 线程去处理同 一个资源2):可以避免 java 中的单继 承的限制3):增加程序的健 壮性,代码可以被多 个线程共享,代码和数据独 立。所以,本人建议大家 劲量实现接口 。?1234567891011121314151617/* author Rollen-Holt* 取得线程的名称* */class helloimplements Runnable public void run() for (int i =0; i 10)try14151617181920212223242526dem
6、o.join(); /强制执行 democatch (Exception e) e.printStackTrace();System.out.println(“main 线程执行“+i);【运行的结果】:main 线程执行0main 线程执行1main 线程执行2main 线程执行3main 线程执行4main 线程执行5main 线程执行6main 线程执行7main 线程执行8main 线程执行9main 线程执行10线程线程线程main 线程执行11main 线程执行12main 线程执行13 线程的休眠:?12345678910111213141516171819/* author R
7、ollen-Holt 线程的休眠* */class helloimplements Runnable public void run() for (int i =0; i 0)tryThread.sleep(1000);catch(InterruptedException e)e.printStackTrace();System.out.println(count-);public static void main(String args) hello he=new hello();Thread h1=new Thread(he);Thread h2=new Thread(he);Thread
8、 h3=new Thread(he);h1.start();h2.start();h3.start();private int count=5;202122232425262728【运行结果】:543210-1这里出现了-1,显然这个是错 的。 ,应该票数不能 为负值。如果想解决这 种问题,就需要使用同 步。所谓同步就是 在统一时间段 中只有有一个 线程运行,其他的线程必 须等到这个线 程结束之后才 能继续执行。【使用线程同步 解决问题】采用同步的话 ,可以使用同步 代码块和同步 方法两种来完 成。【同步代码块】:语法格式:synchronized(同步对象)/需要同步的代 码但是一般都把 当
9、前对象 this 作为同步 对象。比如对于上面 的买票的问题 ,如下:?1234567891011121314151617181920212223/* author Rollen-Holt* */class helloimplements Runnable public void run() for(int i=0;i0)tryThread.sleep(1000);catch(InterruptedException e)e.printStackTrace();System.out.println(count-);public static void main(String args) hel
10、lo he=new hello();Thread h1=new Thread(he);Thread h2=new Thread(he);Thread h3=new Thread(he);h1.start();h2.start();h3.start();private int count=5;24252627282930【运行结果】:(每一秒输出一 个结果)54321【同步方法】也可以采用同 步方法。语法格式为 synchronized 方法返回类型 方法名(参数列表)/ 其他代码现在,我们采用同步 方法解决上面 的问题。?1234567891/* author Rollen-Holt* */c
11、lass helloimplements Runnable public void run() for (int i =0; i 0) try Thread.sleep(1000);catch (InterruptedException e) e.printStackTrace();System.out.println(count-);public static void main(String args) hello he =new hello();Thread h1 =new Thread(he);Thread h2 =new Thread(he);Thread h3 =new Threa
12、d(he);h1.start();h2.start();h3.start();private int count =5;233【运行结果】 (每秒输出一个 )54321提醒一下,当多个线程共 享一个资源的 时候需要进行 同步,但是过多的同 步可能导致死 锁。此处列举经典 的生产者和消 费者问题。【生产者和消费 者问题】先看一段有问 题的代码。?123456789101112131415161class Info public String getName() return name;public void setName(String name) this.name = name;public
13、 int getAge() return age;public void setAge(int age) this.age = age;private String name =“Rollen“;private int age =20;/* 生产者71819202122232425262728293031323334353637383* */class Producerimplements Runnableprivate Info info=null;Producer(Info info)this.info=info;public void run()boolean flag=false;fo
14、r(int i=0;i“+this.info.getAge();/* 测试类* */class hellopublic static void main(String args) Info info=new Info();Producer pro=new Producer(info);Consumer con=new Consumer(info);new Thread(pro).start();new Thread(con).start();162636465666768697071727374757677787980818283848586878889【运行结果】:Rollen100chun
15、Ge20chunGe100Rollen100chunGe20Rollen100Rollen100Rollen100chunGe20chunGe20chunGe20Rollen100chunGe20Rollen100chunGe20Rollen100chunGe20Rollen100chunGe20Rollen100chunGe20Rollen100chunGe20Rollen100chunGe20大家可以从结 果中看到,名字和年龄并 没有对于。那么如何解决 呢?1)加入同步2)加入等待和唤 醒先来看看加入 同步会是如何 。?12345678910111213141516171class Inf
16、o public String getName() return name;public void setName(String name) this.name = name;public int getAge() return age;public void setAge(int age) this.age = age;public synchronized void set(String name,int age)this.name=name;tryThread.sleep(100);catch (Exception e) e.printStackTrace();this.age=age;