------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
< 今日心情 >!!
一、 概述
1.进程
一个正在执行中的程序。
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
2.线程
进程中的一个独立的控制单元。
注:线程可以看成是一条独立的生产线,开启一个线程可以独立运行其中的代码。线程在控制着进程的执行。一个进程中至少有一线程。
二、 创建线程
1.继承Thread类
覆盖父类中的run方法。
线程运行的代码放在run方法中。创建线程
建立子类对象。
数据和线程不分离,每个线程中的数据独立,线程间数据不共享。
开启线程
调用start方法。
2.实现Runnable接口。
覆盖接口中的run方法。创建子类对象。创建线程
格式:
Thread t1=new Thread(Runnable子类对象);
数据和线程分离,创建线程接收对象,线程间数据共享。
开启线程
t1.start();
3.线程的5种状态
class TickThread extends Thread { int con=100;//车站共有100张票 public void run() { while(con>0) System.out.println("您的票是:"+con--); } } class ThreadDemo { public static void main(String[] args) { //创建两个窗口来售票 TickThread t1=new TickThread(); TickThread t2=new TickThread(); t1.start(); t2.start(); } } class Tick implements Runnable { int con=100;//车站共有100张票 public void run() { while(con>0) System.out.println("您的票是:"+con--); } } class ThreadDemo { public static void main(String[] args) { //创建两个窗口来售票 Tick t=new Tick(); Thread t1=new Thread(t); Thread t2=new Thread(t); t1.start(); t2.start(); } }
注:线程有自己的名字,可以通过构造函数,或者setName方法设置。currentThread方法获取当前线程对象,getName获取线程名字
三、线程安全
class TickThread implements Runnable { int con=100;//车站共有100张票 public void run() { while(con>0) { try { Thread.sleep(20);//手动延迟20毫秒 } catch (Exception e) { } System.out.println("您的票是:"+con--); } } } class ThreadDemo { public static void main(String[] args) { //创建两个窗口来售票 TickThread t=new TickThread(); Thread t1=new Thread(t); Thread t2=new Thread(t); t1.start(); t2.start(); } }
1.导致线程安全的原因
多个线程访问出现延迟;
线程随机性 。
注:
线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大 的。
2.同步(synchronized)
格式:
synchronized(对象)
{
//需要同步的代码
}
注:对象如同锁的功能,synchronized如同一个门。当多个synchronized持有同一个对象的时候,一旦有一个线程进入其中的一个synchronized区域,这些synchronized都会处于“锁上”的状态。
好比一楼二楼各有一个厕所,但是用了同一个电子锁,一旦有人进入其中的一个厕所,这两个门都会锁上。别人进不去,只能等着。
3.同步的特点
前提:同步需要两个或者两个以上的线程;多个线程使用的是同一个锁。弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形 中会降低程序的运行效率。
4.同步函数
格式:
在函数上加上synchronized,位置在返回值类型前边。
同步函数用的锁是this。
class Tick { private int con=100; public void put() { System.out.println(Thread.currentThread().getName()+":您的票是:"+con--); } public int getCon() { return con; } } class TickThread implements Runnable { Tick t=new Tick(); public void run() { while(t.getCon()>0) { try { Thread.sleep(20); } catch (Exception e) { } synchronized(this) { if(t.getCon()>0) t.put(); } } } } class ThreadDemo { public static void main(String[] args) { //创建两个窗口来售票 TickThread t=new TickThread(); Thread t1=new Thread(t); Thread t2=new Thread(t); t1.start(); t2.start(); } }
5.线程间通信
其实线程间通信就是在对共享数据进行操作。
注意:
这些方法存在与同步中;
使用这些方法时必须要标识所属的同步的锁。
锁可以是任意对象,所以任意对象调用的方法一定定义Object类中。
wait()和sleep()的区别
wait():释放CPU执行权,释放锁。
sleep():释放CPU执行权,不释放锁。
class Sources { int value=1; private boolean ck=true; public synchronized void set(int value) { while(!ck) { goWait(); } this.value=value; System.out.println(Thread.currentThread().getName()+":输入:"+value); ck=false; this.notifyAll(); } public synchronized int get() { while(ck) { goWait(); } System.out.println(Thread.currentThread().getName()+":输出:"+value); ck=true; this.notifyAll(); return value; } private void goWait() { try { this.wait(); } catch (Exception e) { } } } class InPut implements Runnable { private int i=0; private Sources s; public InPut(Sources s) { this.s=s; } public void run() { while(i<100) { s.set(i++); } } } class OutPut implements Runnable { private Sources s; private int i=0; public OutPut(Sources s) { this.s=s; } public void run() { while(i<100) { i=s.get(); } } } class TongXinDemo { public static void main(String[] args) { Sources s=new Sources(); InPut i=new InPut(s); OutPut o=new OutPut(s); Thread t1=new Thread(i); Thread t2=new Thread(i); Thread t3=new Thread(o); Thread t4=new Thread(o); t1.start(); t2.start(); t3.start(); t4.start(); } }
6.死锁
class DeadThread implements Runnable { private int i=0; Object obj=new Object(); public void run() { if(i++==0) { while(true) { synchronized(obj) { show(); } } } else { while(true) { show(); } } } public synchronized void show() { System.out.println(Thread.currentThread().getName()+"进入办公室……"); synchronized(obj) { System.out.println(Thread.currentThread().getName()+"开始工作……\n"); } } } class DeadThreadDemo { public static void main(String[] args) { DeadThread d=new DeadThread(); Thread t1=new Thread(d); Thread t2=new Thread(d); t1.start(); t2.start(); } }
7.lock
jkd1.5中对同步的升级,将synchronize替换成了lock,将object中的wait,notify,notifyAll替换成立condition对象。import java.util.concurrent.locks.*; class Sources { private int value=0; private Lock lock=new ReentrantLock(); Condition c1=lock.newCondition(); Condition c2=lock.newCondition(); private boolean isIn =true; public void set() { while(value <100) { lock.lock(); try { while(!isIn) { c1.await(); } value++; System.out.println(Thread.currentThread().getName()+":输入:"+value); isIn=false; c2.signal(); } catch (Exception e) { } finally { lock.unlock(); } } } public void get(int max) { int i=0; while(i