黑马程序员-多线程
来源:互联网 发布:上海微创软件待遇 编辑:程序博客网 时间:2024/05/16 00:40
进程:是一个正在执行的程序。
每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行。
一个进程中至少有一个线程。
Java虚拟机启动的时候会有一个进程java.exe,该进程中至少一个线程负责java程序的执行。
而且这个线程运行的代码存在于main方法中,该线程成为主线程。
更细节的说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程。
创建线程:
第一种方式,继承Thread类
1. 定义类继承Thread类
2. 复写Thread类中的run()方法
目的:将自定义代码存储在run方法中,让线程运行
3. 调用线程的start()方法,该方法有两个作用:启动线程,调用run方法。
class demo extends Thread
{
publicvoid run()
{
}
}
多线程的一个特性:随机性,那个线程抢到cpu执行权,哪个就先执行。
线程都有自己默认的名称,通过getName()方法获取,名称是Thread-编号,该编号从0开始。
Thread类的方法:
构造方法设置线程名称:Thread(Stringname),子类直接调用就可以,
classTest extends Thread
{
Test(Stringname)
{
super(name);
}
public voidrun()
{
System.out.println(Thread.currentThread().getName());
}
}
class demo{
publicstatic void main(String []args){
Ttestt1 = new Test(“one”);
Testt2 = new Test(“two”);
t1.start();
t2.start();
}
}
getName()获取线程名称
currentThread()返回当前线程对象,static Thread Thread.currenThread()
第二种方式:实现Runnable接口
1. 定义类实现Runnnable接口
2. 覆盖Runnnable接口中的run方法
3. 通过Thread类建立线程对象
4. 将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
自定义的run方法所属的对象是Runnable接口的子类对象,要让线程去指定指定对象的run方法,就必须明确该run方法所属对象
5. 调用Thread类的start方法启动线程并调用Runnable接口子类的run方法
class Test implements Runnable
{
publicvoid run()
{
System.out.println();
}
}
class demo
{
publicstatic void main()
{
Testt = new Test();
Threadt1 = new Thread(t);
Threadt2 = new Thread(t);
t1.start();
t2.start();
}
}
实现方式和继承方式的区别:
实现方式好处:避免了单继承的局限性。
在定义线程时,建议使用实现方式。
class Test implements Runnable
{
privateint ticket = 100;
publicvoid run()
{
while(true)
{
if(ticket>0) //这里会出现安全问题
{
try{Thread.sleep(10);}catch(Exceptione){}
System.out.println(currentThread().getName()+”….”+ticket--);
}
}
}
}
class demo
{
publicstatic void main()
{
Testt = new Test();
Threadt1 = new Thread(t);
Threadt2 = new Thread(t);
Threadt3 = new Thread(t);
Threadt4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
多线程的运行出现安全问题:
问题原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。
解决:同步代码块
synchronized(对象)
{
需要被同步的代码
}
对象如同锁,持有锁的线程可以在同步中执行。
没有持有锁得线程即使获得cpu的执行权,也进不去,因为没有获取锁
前提:必须是多个线程使用同一个锁
必须要有两个或两个以上的线程
Object obj = new Object();
synchronized(obj)
{
if(ticket>0)
{
try{Thread.sleep(10);}catch(Exceptione){}
System.out.println(currentThread().getName()+”….”+ticket--);
}
}
同步有两种表现形式,一种是同步代码块,一种是同步函数
比如:publicsynchronized void add(int n)
{
Sum= sum+n;
System.out.println(sum);
}
同步函数用的锁:
函数需要被对象调用,那么函数都有一个所属对象引用,this,所以同步函数使用的锁就是this。
静态同步方法使用的锁是该方法所在类的字节码文件对象。 类名.class
懒汉式
class Single
{
privatestatic Single = null;
privateSingle(){}
publicstatic void getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
If(s==null)
{
s = new Single();
}
}
}
return s;
}
}
死锁:同步中嵌套同步
class Test implements Runnable
{
privateboolean flag;
Test(booleanflag)
{
this.flag= flag;
}
publicvoid run()
{
if(flag)
{
synchronized(Mylock.locka)
{
System.out.println("iflocka");
synchronized(Mylock.lockb)
{
System.out.println("iflockb");
}
}
}
else
{
synchronized(Mylock.lockb)
{
System.out.println("elselockb");
synchronized(Mylock.locka)
{
System.out.println("elselocka");
}
}
}
}
}
class Mylock
{
staticObject locka = new Object();
staticObject lockb = new Object();
}
class sisuo{
publicstatic void main(String []args){
Threadt1 = new Thread(new Test(true));
Threadt2 = new Thread(new Test(false));
t1.start();
t2.start();
}
}
- 黑马程序员 多线程
- 黑马程序员:多线程
- 黑马程序员-java多线程
- 黑马程序员--java 多线程
- 黑马程序员_java多线程
- 黑马程序员-java多线程
- 黑马程序员_多线程
- 黑马程序员 多线程
- 黑马程序员_JAVA多线程
- 黑马程序员—多线程
- 黑马程序员- 多线程
- 黑马程序员_多线程
- 黑马程序员--多线程
- 黑马程序员_多线程
- 黑马程序员--Java多线程
- 黑马程序员---多线程
- 黑马程序员__多线程
- 黑马程序员_多线程
- iOS公司开发者账号申请分享攻略
- linux的学生管理系统——C语言命令行实现
- hdu_1074_Doing Homework
- 经典书籍
- MFC程序默认用管理员身份打开,参考360安全卫士
- 黑马程序员-多线程
- Oracle存储过程返回游标实例详解
- Ajax 和 REST,第 2 部分
- java 获取URL
- Mysql启动中 InnoDB: Error: log file ./ib_logfile0 is of different size 0
- 搬迁Mysql的Data目录和Binlog目录
- ubuntu12.04安装Qt4/Qt5错误解决办法
- newInstance()和new
- 程序员的七条军规