黑马训练营-学习笔记----多线程
2012-11-09 20:52
260 查看
------- android培训、java培训、期待与您交流!
----------
进程:是一个正在执行的程序,每一个进程执行都有一个执行的顺序,该顺序就是一个执行路径,或者叫一个控制单元
线程:就是进程中一个独立的控制单元,线程在控制着进程的执行
一个进程中至少有一个线程
Java VM启动时或有一个进程java.exe
该进程中至少有一个线程负责java成语执行,而且这个线程运行的代码存在于main方法中
该线程称之为主线程
其实,jvm启动不止一个线程,还有负责垃圾回收机制的线程
1.在自定义的代码中自定义一个线程
通过对API的查找,java已经提供了对线程的描述,即thread类
创建线程的第一种方法:继承Thread类
步骤:1.定义类继承Thread
2.复写Thread类中的run方法
目的是将自定义的代码存储在run方法中让线程运行
3.调用线程的start方法,该方法有两个作用:启动线程、调用run方法
运行结果每次都不一样,因为多个线程都获取cpu的执行权,cpu执行到谁,谁就运行
明确一点,在某一时刻,只能一个程序在运行(多核除外),cpu在做着快速的切换
以达到看上去同时运行的效果
覆盖run方法
Thread类用于描述线程
该类定义了一个功能,用于存储线程要运行的代码,该存储就是run方法
也就是说Thread类中的run方法用于存储线程要运行的代码
class Demo extends Thread
{
public void run()
{
for(int i = 0;i<100;i++)
System.out.println("demo run"+i);
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();//建立好对象就创建好一个线程
d.start();//开启线程并执行该现成的run方法
//d.run();
仅仅是对象调用方法,而线程并没有运行
for(int i = 0;i<100;i++)
System.out.println("Hello Java"+i);
}
}
创建线程的第二种方式:实现Runnable接口
步骤:
1.定义类实现Runnable接口
2.覆盖Runnable接口中run方法
将线程要运行的代码存放在该run方法中
3.通过Thread类建立线程对象
4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
之所以要将Runnable接口的子类对象传递给Thread的构造函数是
因为自定义的run方法所属的对象是Runnable接口的子类对象,所以
要让线程去执行指定对象的run方法,就必须明确该run方法所属的对象
5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
实现方式和继承方式的区别
实现方式好处在于避免了单继承的局限性,在定义线程时,建议使用实现方式
两种方式的区别还有一点是:
继承Thread:线程代码存放在Thread子类run方法中
实现Runnable,线程代码存在接口的子类的run方法
当各线程判断后进入sleep状态,再次启动时可能会出现打印出
-1,-2等错票,这就是多线程的安全问题
问题的原因在于,当多条语句在操作一个线程共享数据时,一个线程对多条
语句只执行了一部分,另一个线程参与进来执行,导致共享数据的错误
解决办法就是对多条操作共享数据的语句,只能让一个线程都执行完,在执行
过程中,其他线程不可以参与运行
java对于多线程的安全问题提供了专业的解决方式
就是同步代码块
synchronized(对象)
{
需要被同步的代码;
}
对象如同锁,持有锁的线程可以在同步中执行
没持有锁的线程即使获得了cpu的执行权也进不去,因为没有锁
同步的前提:
1.必须要有两个或者两个以上的线程
2.必须是多个线程使用同一个锁
必须保证同步中只能有一个线程在运行
好处在于解决了多线程的安全问题,但弊端在于多个线程都要判断锁,较为消耗资源
JDK1.5以上提供了多线程升级解决方案
将同步synchronized替换成了显示的lock操作
将Object中的wait,notify,notifyAll,替换成了condition对象
该对象可以通过lock锁进行获取
在该示例中实现了本方只唤醒对方操作
结束线程
stop方法已经过时
要停止线程只能,run方法结束
开启多线程运行,运行代码通常是循环结构
只要控制循环,就可以让run方法结束,也就是线程结束
特殊情况
当线程处于冻结状态,线程就不会读取标记,那么线程就不会结束。
当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结状态清除
强制让线程恢复到运行状态,这样可以操作标记让线程结束
Thread类提供了该方法:interrupt();
如何找问题
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
将同步代码块封装成一个函数,就可以定义成同步函数
那么同步函数用的是哪一个锁呢
函数需要被对象调用,那么函数都有一个所属对象引用,就是this
所以同步函数使用的锁是this
如果同步函数被静态修饰后使用的锁不再是this了,因为静态方法中不可以定义this
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象
即:类名.class 该对象的类型是class
静态的同步方法使用的锁是该方法所在类的字节码文件对象 类名.class
单例模式设计
饿汉式
class Single
{
private static 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;
}
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
线程间通讯:
其实就是多个线程在操作同一个资源
但操作动作不同
wait(),notify(),notifyAll()
都使用在同步中,因为要对持有监视器(锁)的线程操作
所以要使用在同步中,因为只有同步才有锁
为什么这些操作线程的方法要定义在object类中呢
因为这些方法在操作同步中线程时,都必须要标识他们所操作线程只有的锁
只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒
也就是说,等待和唤醒必须是同一把锁
而锁可以是任意的对象,所以可以被任意对象调用的方法定义在object类中
------- android培训、java培训、期待与您交流!
----------
----------
进程:是一个正在执行的程序,每一个进程执行都有一个执行的顺序,该顺序就是一个执行路径,或者叫一个控制单元
线程:就是进程中一个独立的控制单元,线程在控制着进程的执行
一个进程中至少有一个线程
Java VM启动时或有一个进程java.exe
该进程中至少有一个线程负责java成语执行,而且这个线程运行的代码存在于main方法中
该线程称之为主线程
其实,jvm启动不止一个线程,还有负责垃圾回收机制的线程
1.在自定义的代码中自定义一个线程
通过对API的查找,java已经提供了对线程的描述,即thread类
创建线程的第一种方法:继承Thread类
步骤:1.定义类继承Thread
2.复写Thread类中的run方法
目的是将自定义的代码存储在run方法中让线程运行
3.调用线程的start方法,该方法有两个作用:启动线程、调用run方法
运行结果每次都不一样,因为多个线程都获取cpu的执行权,cpu执行到谁,谁就运行
明确一点,在某一时刻,只能一个程序在运行(多核除外),cpu在做着快速的切换
以达到看上去同时运行的效果
覆盖run方法
Thread类用于描述线程
该类定义了一个功能,用于存储线程要运行的代码,该存储就是run方法
也就是说Thread类中的run方法用于存储线程要运行的代码
class Demo extends Thread
{
public void run()
{
for(int i = 0;i<100;i++)
System.out.println("demo run"+i);
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();//建立好对象就创建好一个线程
d.start();//开启线程并执行该现成的run方法
//d.run();
仅仅是对象调用方法,而线程并没有运行
for(int i = 0;i<100;i++)
System.out.println("Hello Java"+i);
}
}
创建线程的第二种方式:实现Runnable接口
步骤:
1.定义类实现Runnable接口
2.覆盖Runnable接口中run方法
将线程要运行的代码存放在该run方法中
3.通过Thread类建立线程对象
4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
之所以要将Runnable接口的子类对象传递给Thread的构造函数是
因为自定义的run方法所属的对象是Runnable接口的子类对象,所以
要让线程去执行指定对象的run方法,就必须明确该run方法所属的对象
5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
实现方式和继承方式的区别
实现方式好处在于避免了单继承的局限性,在定义线程时,建议使用实现方式
两种方式的区别还有一点是:
继承Thread:线程代码存放在Thread子类run方法中
实现Runnable,线程代码存在接口的子类的run方法
当各线程判断后进入sleep状态,再次启动时可能会出现打印出
-1,-2等错票,这就是多线程的安全问题
问题的原因在于,当多条语句在操作一个线程共享数据时,一个线程对多条
语句只执行了一部分,另一个线程参与进来执行,导致共享数据的错误
解决办法就是对多条操作共享数据的语句,只能让一个线程都执行完,在执行
过程中,其他线程不可以参与运行
java对于多线程的安全问题提供了专业的解决方式
就是同步代码块
synchronized(对象)
{
需要被同步的代码;
}
对象如同锁,持有锁的线程可以在同步中执行
没持有锁的线程即使获得了cpu的执行权也进不去,因为没有锁
同步的前提:
1.必须要有两个或者两个以上的线程
2.必须是多个线程使用同一个锁
必须保证同步中只能有一个线程在运行
好处在于解决了多线程的安全问题,但弊端在于多个线程都要判断锁,较为消耗资源
JDK1.5以上提供了多线程升级解决方案
将同步synchronized替换成了显示的lock操作
将Object中的wait,notify,notifyAll,替换成了condition对象
该对象可以通过lock锁进行获取
在该示例中实现了本方只唤醒对方操作
结束线程
stop方法已经过时
要停止线程只能,run方法结束
开启多线程运行,运行代码通常是循环结构
只要控制循环,就可以让run方法结束,也就是线程结束
特殊情况
当线程处于冻结状态,线程就不会读取标记,那么线程就不会结束。
当没有指定的方式让冻结的线程恢复到运行状态时,需要对冻结状态清除
强制让线程恢复到运行状态,这样可以操作标记让线程结束
Thread类提供了该方法:interrupt();
如何找问题
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
将同步代码块封装成一个函数,就可以定义成同步函数
那么同步函数用的是哪一个锁呢
函数需要被对象调用,那么函数都有一个所属对象引用,就是this
所以同步函数使用的锁是this
如果同步函数被静态修饰后使用的锁不再是this了,因为静态方法中不可以定义this
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象
即:类名.class 该对象的类型是class
静态的同步方法使用的锁是该方法所在类的字节码文件对象 类名.class
单例模式设计
饿汉式
class Single
{
private static 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;
}
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
线程间通讯:
其实就是多个线程在操作同一个资源
但操作动作不同
wait(),notify(),notifyAll()
都使用在同步中,因为要对持有监视器(锁)的线程操作
所以要使用在同步中,因为只有同步才有锁
为什么这些操作线程的方法要定义在object类中呢
因为这些方法在操作同步中线程时,都必须要标识他们所操作线程只有的锁
只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒
也就是说,等待和唤醒必须是同一把锁
而锁可以是任意的对象,所以可以被任意对象调用的方法定义在object类中
------- android培训、java培训、期待与您交流!
----------
相关文章推荐
- Java反射学习和笔记——黑马训练营
- Java网络学习和笔记——黑马训练营
- Java集合框架之Map集合学习和笔记——黑马训练营
- 黑马训练营-学习笔记----面向对象
- Java抽象和接口的学习和笔记——黑马训练营
- 黑马训练营java学习笔记:数组
- 黑马训练营-学习笔记----JavaAPI
- 黑马训练营学习笔记
- 黑马训练营java学习笔记:异常
- 黑马训练营热身课程学习笔记1-其他对象(System)
- [好程序员训练营]----java基础之多线程部分学习笔记
- 黑马训练营java学习笔记:集合
- 黑马训练营java学习笔记:自动装箱与拆箱(AutoBoxing/unboxing)
- 黑马训练营-学习笔记----JavaIO
- 黑马学习笔记_多线程
- 黑马训练营-学习笔记----图形用户界面
- 黑马训练营java学习笔记:输入/输出
- Java线程学习和笔记——黑马训练营
- 黑马训练营-学习笔记----网络编程
- Java字节流和字符流学习和笔记——黑马训练营