从网上看了许多有关java多线程的讲解,也作笔记总结一下。java
1.实现Runnable接口相比于继承Thread类:
多线程
(1)适合多个相同的程序代码的线程去处理同一个资源jvm
(2)能够避免java中的单继承的限制ide
(3)代码能够被多个线程共享,代码和数据独立this
public class Test { public static void main(String[] args) { for(int i=0;i<5;i++){ Thread t = new MThread(); t.start(); } try{ Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } R r = new R(); for(int i=0;i<5;i++){ Thread t = new Thread(r); t.start(); } } } class MThread extends Thread{ public int x = 0; public void run() { System.out.print(++x); } } class R implements Runnable{ private int x = 0; public void run() { System.out.print(++x); } } 执行结果:1111112345
2.main方法也是一个线程。在java中全部的线程都是同时启动的,而何时哪一个线程先执行,取决于CPU的资源。spa
在java中,每次程序至少启动2个线程,一个是main线程,一个是垃圾收集线程。由于使用java命令执行一个类时,实际上都会启动一个JVM,每一个JVM其实就是在操做系统中启动了一个进程。操作系统
3.线程的强制执行:线程
public class A implements Runnable { public void run() { for(int i=0;i<3;i++){ System.out.println(Thread.currentThread().getName()); } } public static void main(String[] args) { A a = new A(); Thread t = new Thread(a); t.start(); for(int i=0;i<5;i++){ if(i>3){ try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("main thread execute-->"+i); } } } 执行结果:当i>3时,若线程Thread-0为执行完,则强制执行线程Thread-0 main thread execute-->0 main thread execute-->1 main thread execute-->2 Thread-0 main thread execute-->3 Thread-0 Thread-0 main thread execute-->4
3.线程的中断code
public class B implements Runnable { public void run() { System.out.println("execute run()"); try{ Thread.sleep(10000); System.out.println("thread finish sleep"); }catch (InterruptedException e){ System.out.println("thread interrupted"); return; } System.out.println("thread end"); } public static void main(String[] args) { B b = new B(); Thread t = new Thread(b); t.start(); try{ Thread.sleep(2000); }catch (InterruptedException e){ e.printStackTrace(); } t.interrupt(); } } 执行结果:execute run() thread interrupted
4.线程的优先级:并不是优先级越高就先执行。谁先执行取决于谁先取得CPU资源。因此setPriority不必定起做用的,在不一样的操做系统不一样的jvm上效果也可能不一样。操做系统也不能保证设置了优先级的线程就必定会先运行或获得更多的CPU时间。对象
public class C implements Runnable { @Override public void run() { for(int i=0;i<3;i++){ System.out.println(Thread.currentThread().getName()+" execute" + i); } } public static void main(String[] args) { Thread a = new Thread(new C(), "A"); Thread b = new Thread(new C(), "B"); Thread c = new Thread(new C(), "C"); a.setPriority(3); b.setPriority(1); c.setPriority(2); a.start(); b.start(); c.start(); } } 执行结果: C execute0 B execute0 A execute0 B execute1 C execute1 B execute2 A execute1 C execute2 A execute2
5.线程的礼让:使用yield(),将一个线程的操做暂时交给其余线程执行
public class D implements Runnable { @Override public void run() { for(int i=0;i<5;++i){ System.out.println(Thread.currentThread().getName()+" execute "+i); if(i==3){ System.out.println(Thread.currentThread().getName()+" thread 礼让"); Thread.currentThread().yield(); } } } public static void main(String[] args) { Thread a = new Thread(new D(), "a"); Thread b = new Thread(new D(), "b"); a.start(); b.start(); } } 执行结果:当a线程执行了yield(),若b线程还没有执行完毕,即交给b线程执行。 b execute 0 a execute 0 b execute 1 a execute 1 b execute 2 a execute 2 b execute 3 a execute 3 b thread 礼让 a thread 礼让 b execute 4 a execute 4
6.同步(同步代码块和同步方法)
同步代码块: public class E implements Runnable { private int count=5; @Override public void run() { for (int i=0;i<10;i++){ synchronized (this){ if(count>0){ try { Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+","+count--); } } } } public static void main(String[] args) { E e = new E(); Thread a = new Thread(e,"a"); Thread b = new Thread(e,"b"); Thread c = new Thread(e,"c"); a.start(); b.start(); c.start(); } } 同步方法: public class E implements Runnable { private int count=5; @Override public void run() { for (int i=0;i<10;i++){ sale(); } } public synchronized void sale(){ if(count>0){ try{ Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+","+count--); } } public static void main(String[] args) { E e = new E(); Thread a = new Thread(e,"a"); Thread b = new Thread(e,"b"); Thread c = new Thread(e,"c"); a.start(); b.start(); c.start(); } } 执行结果:因为a,b,c三个线程都是用的e对象锁,因此a执行时,b,c等待 a,5 a,4 a,3 a,2 a,1
7.生产者消费者问题
public class G { public static void main(String[] args) { Info info = new Info(); Producer p = new Producer(info); Consumer c = new Consumer(info); new Thread(p,"p").start(); new Thread(c,"c").start(); } } class Info{ private boolean flag = false; private String name="aa"; private int age = 10; String getName() { return name; } void setName(String name) { this.name = name; } int getAge() { return age; } void setAge(int age) { this.age = age; } public synchronized void set(String name, int age){ if(!flag){ try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name; try{ Thread.sleep(100); }catch (InterruptedException e){ e.printStackTrace(); } this.age = age; flag = false; super.notify(); } public synchronized void get(){ if(flag){ try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try{ Thread.sleep(100); }catch (InterruptedException e){ e.printStackTrace(); } System.out.println(this.getName()+"--"+this.getAge()); flag = true; super.notify(); } } class Producer implements Runnable{ private Info info = null; Producer(Info info){ this.info = info; } public void run() { boolean flag = false; for(int i=0;i<5;++i){ if(flag){ this.info.set("aa", 10); flag = false; }else{ this.info.set("zz", 99); flag = true; } } } } class Consumer implements Runnable{ private Info info = null; Consumer(Info info){ this.info = info; } public void run() { for(int i=0;i<5;++i){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.get(); } } } 执行结果: aa--10 zz--99 aa--10 zz--99 aa--10