黑马程序员——多线程(上)——第11天
来源:互联网 发布:欢乐升级mac版 编辑:程序博客网 时间:2024/04/29 10:20
——- android培训、java培训、期待与您交流! ———-
1.1,多线程概述
1,进程:是一个正在执行中的程序,每一个进程执行都有一个执行顺序。
该顺序是一个执行路径,或者叫一个控制单元。
2,线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行,
一个进程中至少有一个线程。
3,多线程:一个进程中有多个线程执行的方式,就叫做多线程。
1.2,线程的创建方式一(继承Thread类)
1,继承Thread类。
步骤:
(1),定义类继承Thread。
(2),复写Thread类中的run方法。
目的:将自定义代码存储在run方法。让线程运行。
(3),调用线程的start方法,该方法两个作用:启动线程,调用run方法。
2,多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说了算。
3,为什么要覆盖run方法呢?
Thread类中的run方法,用于存储线程要运行的代码。
4,static Thread currentThread():获取当前线程对象。
getName(): 获取线程名称。
设置线程名称:setName或者构造函数。
示例:
//继承Thread类class Demo extends Thread{ public void run() { for(int x=0; x<60; x++) System.out.println("demo run----"+x); }}class ThreadDemo { public static void main(String[] args) { //for(int x=0; x<4000; x++) //System.out.println("Hello World!"); Demo d = new Demo();//创建好一个线程。 d.start();//开启线程并执行该线程的run方法。 d.run();//仅仅是对象调用方法。而线程创建了,并没有运行。 for(int x=0; x<60; x++) System.out.println("Hello World!--"+x); }}
1.3,线程的创建方式二(实现Runable接口)
1,实现Runable接口
步骤:
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法。
将线程要运行的代码存放在该run方法中。
3,通过Thread类建立线程对象。
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
为什么要将Runnable接口的子类对象传递给Thread的构造函数。
因为,自定义的run方法所属的对象是Runnable接口的子类对象。
所以要让线程去指定对象的run方法。就必须明确该run方法所属对象。
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
示例:
//实现Runnable接口class Ticket implements Runnable//extends Thread{ private int tick = 100; public void run() { while(true) { if(tick>0) { System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--); } } }}class TicketDemo{ public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t);//创建了一个线程; Thread t2 = new Thread(t);//创建了一个线程; Thread t3 = new Thread(t);//创建了一个线程; Thread t4 = new Thread(t);//创建了一个线程; t1.start(); t2.start(); t3.start(); t4.start(); /* Ticket t1 = new Ticket(); //Ticket t2 = new Ticket(); //Ticket t3 = new Ticket(); //Ticket t4 = new Ticket(); t1.start(); t1.start(); t1.start(); t1.start(); */ }}
1.4,实现方式和继承方式的区别
1,实现方式避免了单继承的局限性。
2,继承Thread方式:线程代码存放在Thread子类的run方法中。
实现Runnable方式:线程代码存放在接口子类的run方法。
1.5,线程安全
1,多线程安全问题产生的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行。导致共享数据的错误。
2,解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
即可以采用线程同步的方式解决线程安全问题。
1.6,同步代码块
1,synchronized(对象)
{
需要被同步的代码
}
对象如同锁。持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
2,同步的前提:
(1),必须要有两个或者两个以上的线程。
(2),必须是多个线程使用同一个锁。
3,同步的利弊
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
示例:
//用synchronized同步代码块方式解决线程安全问题class Ticket implements Runnable{ private int tick = 1000; Object obj = new Object(); public void run() { while(true) { synchronized(obj) { if(tick>0) { //try{Thread.sleep(10);}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--); } } } }}class TicketDemo2{ public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); Thread t4 = new Thread(t); t1.start(); t2.start(); t3.start(); t4.start(); }}
1.7,同步函数
1,同步函数:在函数上加上synchronized修饰符即可。
2,同步函数用的是哪一个锁呢?
函数需要被对象调用。那么函数都有一个所属对象引用。就是this。
所以同步函数使用的锁是this。
示例:
//非静态同步函数用的锁为thisclass Ticket implements Runnable{ private int tick = 100; Object obj = new Object(); boolean flag = true; public void run() { if(flag) { while(true) { synchronized(this) { if(tick>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"....code : "+ tick--); } } } } else while(true) show(); } public synchronized void show()//this { if(tick>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--); } }}class ThisLockDemo{ public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); try{Thread.sleep(10);}catch(Exception e){} t.flag = false; t2.start();// Thread t3 = new Thread(t);// Thread t4 = new Thread(t);// t3.start();// t4.start(); }}
3,静态同步函数
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
类名.class 该对象的类型是Class
示例:
//静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.classclass Ticket implements Runnable{ private static int tick = 100; //Object obj = new Object(); boolean flag = true; public void run() { if(flag) { while(true) { synchronized(Ticket.class) { if(tick>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"....code : "+ tick--); } } } } else while(true) show(); } public static synchronized void show() { if(tick>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--); } }}class StaticMethodDemo{ public static void main(String[] args) { Ticket t = new Ticket(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); t1.start(); try{Thread.sleep(10);}catch(Exception e){} t.flag = false; t2.start(); }}
1.8,单例设计模式中的同步代码块
示例:
/*单例设计模式。*///饿汉式。/*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) //--->A; s = new Single(); } } return s; }}class SingleDemo { public static void main(String[] args) { System.out.println("Hello World!"); }}
1.9,死锁
1,死锁:同步中嵌套同步,就有可能出现死锁的情况。
示例:
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(Thread.currentThread().getName()+"...if locka "); synchronized(MyLock.lockb) { System.out.println(Thread.currentThread().getName()+"..if lockb"); } } } } else { while(true) { synchronized(MyLock.lockb) { System.out.println(Thread.currentThread().getName()+"..else lockb"); synchronized(MyLock.locka) { System.out.println(Thread.currentThread().getName()+".....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(); }}
——- android培训、java培训、期待与您交流! ———-
- 黑马程序员——Java基础---多线程(上)--第11天--第127-141集
- 黑马程序员——多线程(上)——第11天
- 黑马程序员——多线程(上)
- 黑马程序员——多线程(上)
- 黑马程序员——多线程第一天
- 黑马程序员——多线程第三天
- 黑马程序员——第11天——多线程(1/2)
- 黑马程序员_Java面对对象——多线程(上)
- 黑马程序员——Java基础__多线程(上)
- 黑马程序员—多线程(上)-线程及其创建方法
- 黑马程序员——Java基础---多线程(下)--第12天--第142-151集
- 黑马程序员—多线程
- 黑马程序员—多线程
- 黑马程序员—多线程
- 黑马程序员—多线程
- 黑马程序员—多线程
- 黑马程序员—多线程
- 黑马程序员—多线程
- 多线程访问HashMap容易犯的错误
- TCP/IP详解 卷I:协议 のFAQ
- LeetCode(230)Kth Smallest Element in a BST
- 多线程下载
- python字典模拟登陆
- 黑马程序员——多线程(上)——第11天
- HDU 5301(Buildings-贪心构造)
- HDU 5391 Zball in Tina Town
- 实模式和保护模式
- 【您的凭证不工作】win7远程桌面提示,请输入新凭据。登录没有成功
- 《C算法》读书笔记 (4):Hello,Joseph!
- linux下进程的最大线程数、进程最大数、进程打开的文件数
- 1151 - Buy or Build (最小生成树)
- 股市风暴下的雪球架构改造经验分享