------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
首先介绍下基本概念:
1, 进程:简单地讲,是一个正在执行的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫做控制单元。
2, 线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。一个进程中至少有一个线程。
3,Jvm 启动的时候会有一个进程 java.exe.该进程中至少一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。其实,jvm启动不止一个线程,还有一个负责垃圾回收机制的线程。
一:关于java多线程的实现问题:
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。
对于直接继承Thread的类来说,代码大致框架是:
class类名extendsThread{
方法1;
方法2;
…
publicvoidrun(){
// other code…
}
属性1;
属性2;
…
}
注意主函数中要用d.start()方法开启线程并执行该线程的run方法。
通过实现Runnable接口:代码大致框架是:
class 类名 implements Runnable{
方法1;
方法2;
…
public void run(){
// other code…
}
属性1;
属性2;
…
}
Thread类继承的一个例子:
class hello extends Thread {
public void run() {
for (int i = 0; i < 7;i++) {
if(count > 0) {
System.out.println("count=" + count--);
}
}
}
public static void main(String[] args) {
hello h1 = new hello();
hello h2 = new hello();
hello h3 = new hello();
h1.start();
h2.start();
h3.start();
}
private int count = 5;
}
运行结果如下:
count=5
count=4
count=3
count=2
count=1
count=5
count=4
count=3
count=2
count=1
count=5
count=4
count=3
count=2
count=1
如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享。
我们换为Runnable接口
Runable接口的例子:
class MyThread implements Runnable{
private int ticket = 5; //5张票
public void run() {
for (int i=0; i<=20;i++) {
if(this.ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖票"+this.ticket--);
}
}
}
}
public class lzwCode {
public static void main(String [] args) {
MyThread my = new MyThread();
new Thread(my, "1号窗口").start();
new Thread(my, "2号窗口").start();
new Thread(my, "3号窗口").start();
}
}
运行结果:
1号窗口正在卖票5
1号窗口正在卖票4
2号窗口正在卖票3
2号窗口正在卖票1
1号窗口正在卖票2
可以得出,实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
所以大家劲量实现runable接口。
二,关于多线程的安全问题:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
来看看一个例子:一个简单的买票系统。
public void run() {
for(int i=0;i<10;++i){
if(count>0){
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
public static void main(String[] args) {
hello he=new hello();
Thread h1=new Thread(he);
Thread h2=new Thread(he);
Thread h3=new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count=5;
}
运行结果:
5
4
3
2
1
0
-1
出现了-1,显然这个是错的。应该票数不能为负值。
如果想解决这种问题,就需要使用同步。所谓同步就是在统一时间段中只有有一个线程运行,其他的线程必须等到这个线程结束之后才能继续执行。
使用线程同步解决问题
采用同步的话,可以使用同步代码块和同步方法两种来完成。
同步代码块:
语法格式:
synchronized(同步对象){
//需要同步的代码
}
但是一般都把当前对象this作为同步对象。
比如对于上面的买票的问题,如下:
class hello implements Runnable {
public void run() {
for(int i=0;i<10;++i){
synchronized(this) {
if(count>0){
try{
Thread.sleep(100);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
}
public static void main(String[] args) {
hello he=new hello();
Thread h1=new Thread(he);
Thread h2=new Thread(he);
Thread h3=new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count=5;
}
运行结果:
5
4
3
2
1
现在来看看同步方法。
语法格式为synchronized 方法返回类型方法名(参数列表){
// 其他代码
}
class hello implements Runnable {
public void run() {
for (int i = 0; i < 10;++i) {
sale();
}
}
public synchronized void sale() {
if (count > 0) {
try{
Thread.sleep(100);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count--);
}
}
public static void main(String[] args) {
hello he = new hello();
Thread h1 = new Thread(he);
Thread h2 = new Thread(he);
Thread h3 = new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count = 5;
}
运行结果
5
4
3
2
1
对同步总结:
同步的前提:
1 : 必须要有两个或者两个以上的线程。
2,必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
三,单例设计模式
有两种。懒汉式和饿汉式
两种模式的区别:
懒汉式的特点是用于延迟加载。这种特点也会出现问题。
如果多线程访问时会出现安全问题。可以加同步的方式来解决。用同步代码块和同步函数都行。但是稍微有点低效,用判断的方式可以决绝效率问题。注意加同步的时候使用的锁是该类所属的字节码文件对象。
饿汉式class Lesson
{
private static finalSingle s = new Lesson ();
private Lesson (){}
public static Single getInstance()
{
return s;
}
}
懒汉式:
class Lesson
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
If(a==null)
{
Synchronized(Single.class)
{
If(a==null)
s = new Single();
}
}。
return s;
}
}
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------