标签:
/* 进程:是一个正执行的程序 每一个进程执行都有一个执行顺序,该顺序是一个执行路径 ,或者叫一个控制单元 线程:就是进程中一个独立的控制单元 线种在控制着进程的执行 一个进程至少有一个线程(控制单元) java vm启动的时候会有一个进程java.exe 该进程中至少有一个线程负责java程序的执行 而且这个线程运行的代码 存在于main方法中 该线程称之为主线程。 扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程 1.如何在自定义代码中,自定义一个线程呢? 通过对api的查找,java已经提供了对线程这类事物的描述therad类 创建线程的第一种方式:继承Thread类 步骤: 1.定义类继承thread 2.复写Thread类中run方法 目的:将自定义代码存储run方法,让线程运行 3.调用线程的start方法 该方法有两个作用,启动,调用run方法 发现运行结果每一次都不同 因为多个线程获取cpu的执行权,cpu执行到谁,谁就运行' 明确一点,在某一个时刻,只能有一个程序在运行(多核除外) cpu在做着快速的切换,以达到看上去是同时运行的效果 我们可以形象把多线程的运行行为在互相抢夺cpu的执行权 这就是多线程的一个特性:随机性,谁抢到谁执行,至于执行多长,cpu说了算 为什么要覆盖run方法呢? Thread类用于描述线程 。 该类就定义了一个功能,用于存储线程要运行的代码 .该存储功能就是run方法 也就是说thread类的run方法,用于存储 线程要运行的代码 */ class Demo extends Thread { public void run() { for(int x=0;x<60;x++){ System.out.println(" demo run---"+x); } } } public class ThreadDemo { public static void main(String[] args) { Demo d = new Demo(); //d.start();//开启线程,并执行该线程的run方法 d.run();//仅仅是对象调用了方法, 而线程创建并没有执行 for(int x=0;x<60;x++){ System.out.println(" hello world run---"+x); } } } /* 原来线程都有自己默认的名称 Thread-编号 该编号从0开始 static Thread currentThread():获取当前线程对象 getName():获取线程名称 设置线程名称:setName或者构造函数 */ class Test extends Thread { public Test(String name){ super(name); } public void run() { for (int x = 0; x < 60; x++) { System.out.println((currentThread()==this)+"..."+this.getName()+" run..." + x); } } } public class ThreadTest { public static void main(String[] args) { Test t1=new Test("线程1"); Test t2=new Test("线程2"); t1.start(); t2.start(); for (int x = 0; x < 60; x++) { System.out.println("main run..." + x); } } } /* 步骤: 1.定义实现Runnable接口 2.覆盖Runnable接口中的Run方法 将该线程要运行的代码 放在run方法中 3.通过Thread类建立线程对象 4.将Runnable接口的子类对象作为实际参数传递给therad类的构建函数 为什么 要将Runnable接口的子类对象传递给Thread的构造函数. 因为,自定义的Run方法所属的对象是runnable接口的子类对象 所以要让线程去指定对象的Run方法,就必须明确该Run方法所属对象 5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法 实现方式和继承方式的区别: 继承Thread:线程代码存放在Thread子类Run方法中 实现Runnable:线程代码存放在接口的子类的Run方法 实现Runnable避免单继承的局限性 多线程的运行出现了安全问题 问题原因: 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完 别一个线程参与进来执行,导致共享数据的错误 解决办法: 对多对操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行 java对多纯种的安全问题提供了专业的解决方式。 就是同步代码块 synchronized(对象){ 需要同步的代码块 } 对象如同锁,持有钢梁的线程可以在同步中执行 没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁 同步的前提: 1.必须要有两个或者两个以上的线程 2.必须是多个线程使用同一个锁 必须保证同步中只能有一个线程在运行 好处:解决了多线程的安全问题 弊端:多个线程需要判断锁,较为消耗资源 */ class Ticket implements Runnable { // private static int ticket=100;//使用静态,一般不使用静态,生命周期过长 private static int tickets = 100; boolean flag=true; public void run() { if (flag) { while (true) { sale();// 调用同步代码块 } } else { while (true) { saleTicket();// 调用同步函数 } } } public void sale() { synchronized (Ticket.class) {//同步代码块,this锁 if (tickets > 0) { System.out.println(Thread.currentThread().getName()+"...code..." + "正在卖第" + tickets + "号票"); try { Thread.sleep(10); } catch (Exception e) { System.out.println(e.getMessage()); } tickets--; } } } /* 同步函数用的是那个锁呢? 函数需要被对象调用,那么函数都有一个所属对象引用 。就是this 如果同步函数使用静态修饰后,使用的是什么 呢? 通过验证,发现不再是this.因为静态方法中也不可以定义this 静态进内存,内在中没有本类对象,但是一定有该类对应的字节码对象。 类名.class,该对象的类型是class */ public static synchronized void saleTicket() {//同步函数,this锁 if (tickets > 0) { System.out.println(Thread.currentThread().getName()+"...show..." + "正在卖第" + tickets + "号票"); try { Thread.sleep(10); } catch (Exception e) { System.out.println(e.getMessage()); } tickets--; } } } public class TicketDemo extends Thread { public static void main(String[] args) { Ticket t1=new Ticket(); new Thread(t1,"售票窗口1").start(); try{Thread.sleep(10);//主线程休息10s }catch(Exception e){} t1.flag=false; new Thread(t1,"售票窗口2").start(); } } /* 单例设计模式 //饿汉式 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 Single getInstance() { //双重判断,减少锁判断次数 if(s==null){ synchronized(Single.class){//使用的锁是所在类的字节码 if (s == null) { s = new Single(); } } } return s; } } public class SingleDemo { public static void main(String[] args) { System.out.println("Hello world!"); } } /* 死锁Demo */ class DeadLockTest implements Runnable { private boolean flag; public DeadLockTest(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 lockb"); } } } } 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(); } public class DeadLockDemo { public static void main(String[] args) { Thread t1 = new Thread(new DeadLockTest(true)); Thread t2 = new Thread(new DeadLockTest(false)); t1.start(); t2.start(); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u012750578/article/details/47067531