好贷网好贷款

黑马程序员--java基础整理十一(多线程1)

发布时间:2016-12-3 6:17:29 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"黑马程序员--java基础整理十一(多线程1)",主要涉及到黑马程序员--java基础整理十一(多线程1)方面的内容,对于黑马程序员--java基础整理十一(多线程1)感兴趣的同学可以参考一下。

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ---------------------- 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。 线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。一个进程中至少有一个线程。 创建新执行线程的方法: 1,声明为Thread的子类。该子类重写Thread类的run方法。 步骤:1,定义类继承Thread。2,复写Thread类中的run方法,目的是将自定义方法存储在run方法中让线程运行。3,调用线程的start方法,该方法有两个作用:启动线程,调用run方法。 class PrineThread extends Thread { long minPrine; PrineThread(long minPrine) { this.minPrine = minPrine; } } public void run()//重写run方法。 { //compute primes larger than minPrine } PrineThread p = new PrineThread(143);//创建好一个线程, p.start();//启动线程操作,调用run方法。 多线程在运行时每一次的结果都不一样,因为多个线程都在获取cpu的执行权,cpu执行到谁谁就运行, 在某一时刻只有有一个程序在运行,多核处理器除外,cpu在做着快速切换看上去是同时运行其实不是, 体现了多线程的随机性特点。 为什么要覆盖run方法呢? Thread类用于描述线程。该类就定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法。 线程都有自己的默认名称,Thread-编号,从编号0开始。命名直接super访问父类即可 Thread.currentThread().getName()获取当前线程名称。也可理解为this.getName(). static Thread currentThread():获取当前线程对象。getName():获取线程名称。设置线程名称:setName或者构造函数 2,创建线程的另一种方法是声明实现Runnable接口类,该类然后实现run方法,然后可以分配该类的实例,在创建Thread时作为一个参数来传递并启动。 步骤:1,定义类实现Runnable接口 2,覆盖Runnable接口中的run方法,将线程要运行的代码存放在该run方法中。  3,通过Thread类建立线程对象。4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数  因为,自定义的run方法所属的对象是Runnable接口的子类对象,所以要用线程去指定对象的run方法,就必须明确该run方法所属对象。  5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。 class PrineRun implements Runnable { long minPrine; PrineRun(long minPrine) { this.minPrine = minPrine } public void run() { //compute primes larger than minPrine } } 下列代码创建并启动线程 PrineRun p = new Prine(123); new Thread(p).start(); 卖票实例: class Ticket extends Thread { private static int tick = 100; public void run() { while(tick>0) { if (tick>0) { System.out.println(Thread.currentThread().getName()+tick--); } } } } class TickDemo { public static void main(String[]args) { Tick t1 = new Tick(); Tick t2 = new Tick(); Tick t3 = new Tick(); t2.start(); t1.start(); t4.start(); } } 采用实现Runnable方法 class Ticket implements Runnable { private int tick = 100; public void run() { while(tick>0) { if (tick>0) { System.out.println(Thread.currentThread().getName()+"--"+tick--); } } } } class TickDemo { public static void main(String[]args) { Ticket t1 = new Ticket(); //Thread t2= new Thread(t1) new Thread (t1).start(); new Thread (t1).start(); new Thread (t1).start(); } } 实现方式和继承方式的区别:实现方式的好处:避免了单继承的局限性,在定义线程时,建议使用实现方式。 区别在于:继承Thread:线程代码存放在Thread子类run方法中 实现Runnable,线程代码存在接口的子类run方法中。 多线程的安全问题:即出现错误数据,如购票出现0号,-1号票。 问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没执行完, 另一个线程参与进来执行,导致共享数据的错误。 解决办法:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。 java对多线程的安全问题提供了专业的解决方式,即同步代码块,可以确保一个线程执行完下一个线程才会执行。 synchronized(对象)直接建立Object的对象传进来即可 { 需要被同步的代码 } Object obj = new Object(); synchronized(obj) { if (tick>0) { System.out.println(Thread.currentThread().getName()+"--"+tick--); } } 对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取cpu的执行权,也进不去。 同步前提:1,必须要有两个或者两个以上的线程。2,必须是多个线程使用同一个锁 必须保证同步中只能有一个线程在运行,好处:解决了多线程的安全问题 弊端:多个线程都要判断锁,比较消耗资源。 try{Thread.sleep();}catch (Exception e){}休眠功能用法 如何找问题: 1,明确哪些代码是多线程运行代码。 2,明确共享数据, 3,明确多线程运行代码中哪些语句是操作共享数据的。 public synchronized void add(int n){}同步函数 和同步代码块功能类似 同步函数用的是哪一个锁? 函数需要被对象调用,所以函数都要有一个所属对象的引用就是this public void run() { while (tick>0) { this.show(); } } public synchronized void show() { if (tick>0) { System.out.println(Thread.currentThread().getName()+"--"+tick--); } } 同步函数静态修饰后不再是this,因为静态方法中不存在this。静态进内存中内存中没有本类对象,但是一定有该类对应的字节码文件对象 类名.class该对象的类型是class 静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class class Ticket extends Thread { private static int tick = 100; public void run() { while(true) { synchronized (Ticket.class) { if (tick>0) { System.out.println(Thread.currentThread().getName()+tick--); } } } } } 饿汉式: class Single { private static final Single s = new Single(); private Single(){} public static Single getInstance() { return s; } } 懒汉式: class Single { private static Single s = null; private Single(){} public static synchronized Single getInstance() { if (s==null) { s=new Single; return s; } } } 重点: class Single { private static Single s = null; private Single(){} public static Single getInstance() { if (s==null) { synchronized(Single.class)//该类对应的字节码文件对象 { if (s==null) { s=new Single; return s; } } } } } 死锁:同步中嵌套同步 class Test implements Runnable { private boolean flag; Test (boolean flag) { this.flag = flag; } public void run() { if (flag) { while(true) { synchronized(MyLock.locka) { System.out.println("if locka"); synchronized(MyLock.lockb) { System.out.println("if lockn"); } } } } else { while (true) { synchronized(MyLock.lockb) { System.out.println("else lockb"); synchronized(MyLock.locka) { System.out.println("else locka"); } } } } } } class MyLock { static Object locka = new Object(); static Object lockb = new Object(); } class DeadLockTest { public static void main(String[]args) { Thread t1 = new Thread(new Test(true)); Thread t2 = new Thread(new Test(false)); t1.start(); t2.start(); } } ---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ---------------------- 详细请查看:<a href="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>

上一篇:黑马程序员--java基础整理十(面向对象6)
下一篇:最大连续和(hdu1003)

相关文章

相关评论