黑马程序员_JAVA多线程_1

             -----------  android培训 java培训 、java学习型技术博客、期待与您交流! ------------

一、多线程的概念:要理解多线程得先了解线程和进程的概念。进程是操作系统结构的基础;是一个正在执行的程序;计算机中正在运行的程序实例。它可能存在多条执行路径。而一个线程就是进程的一个执行路径。线程是进程中的内容,程序中的独立控制单元,每一个线程执行都有一个执行顺序。

二、多线程的好处:没有多线程就没有用户交互界面。当然,多线程也可能会提高程序的运行效率。我一个任务没有必要等待另一个任务的完成。多线程还有很多其他优点。

三、多线程的坏处:使用多线程虽然有很多好处,但是也有它的不好的地方。其中一个是,设计不好多线程可能就会发生死锁,或者集体等待。其他的坏处还有,线程太多,会影响性能;占用跟多的内存。

四、JAVA多线程的实现:在JAVA中有两种方法来实现多线程。一个是拓展Thread类,一个是实现Runnable接口。

拓展方法:1、继承Thread类 。

 2、覆盖Thread类里面的run()方法。

 3、创建并启动一个线程。启动用的是start()方法。线程启动后,JVM就会启动run()方法来执行线程。

示例:

public class NewThreadMethod1 {
	public static void main(String[] args) {
		NewThread newThread = new NewThread();
		newThread.start();
		new NewThread().start();
	}

	
}
class NewThread extends Thread{
	@Override
	public void run() {
		int i = 0;
		while (i < 100) {
			System.out.println(currentThread().getName() + "  lailongwei");
			i++;
		}
	}
}


这里解释下,run()方法是自定义代码的地方。线程运行的代码块。由JVM来调用。start方法是开启线程,并在线程中执行run()方法。

实现方法:1、定义类,实现接口。

2、覆盖Runnable接口中的run方法。

3、把这个类当作参数传递给Thread的构造函数,并启动线程。(new Thread(Runnable).start())。

示例:

public class NewThreadMethod2 {
	public static void main(String[] args) {
		new Thread(new NewRunnable()).start();
		new Thread(new NewRunnable()).start();
	}
}
class NewRunnable implements Runnable{

	@Override
	public void run() {
		int i = 0;
		while (i < 100) {
			System.out.println(Thread.currentThread().getName() + "  lailongwei");
			i++;
		}
	}
	
}

五、拓展方法和实现方法的区别:1、JAVA中只能有一个extends,实现方法的好处,避免了单继承的局限性。在定义多线程时,建议使用实现方法。

2、Runnable任务可以被多线程同时使用。而拓展方法不可以。

3、线程代码存放的位置不一样。

六、线程的状态:


需要注意的阻塞状态和等待状态的区别,阻塞状态是等待CPU的执行权,具备运行资格。等待状态是放弃了执行资格。

七、线程的标识:线程可以通过setName方法活或者Thread(String name)方法来设置自己的表示名称。一般情况下,线程的标识是“Thread-编号”。可以通过getName,

Thread.currentThread().getName()方法来获取标识。

八、多线程的运行出现安全问题。

1、出现安全问题的原因是,当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程就参与进来。导致错误的发生。

示例如下:

public class ThreadError {
	public static void main(String[] args) {
		new Thread(new Count()).start();
		new Thread(new Count()).start();
		new Thread(new Count()).start();
	}
	
}
class Count implements Runnable{
	int count = 0;
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			count = i;
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			count--;
			System.out.println(Thread.currentThread().getName() + "::" + count);
		}

		
	}
	
}

2、如何找多线程的安全问题:a,明确有哪些共享数据。b、明确哪些语句是操作共享数据的。

3、解决方法。有两种解决办法。一个是同步代码块。一个是编写同步函数。

同步代码块的

a、问题代码用同步代码块的解决:

public class ThreadError {
	public static void main(String[] args) {
		new Thread(new Count()).start();
		new Thread(new Count()).start();
		new Thread(new Count()).start();
	}
	
}
class Count implements Runnable{
	int count = 0;
	@Override
	public void run() {
		synchronized (Runnable.class) {
			for (int i = 0; i < 100; i++) {
				count = i;
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				count--;
				System.out.println(Thread.currentThread().getName() + "::" + count);
			}
		}


		
	}
	
}
就是把需要同步的语句放到同步代码块中。这里用的锁是Runnable.class。 也就是synchronich()括号中的类。

b、用同步函数解决:

public class ThreadError {
	public static void main(String[] args) {
		new Thread(new Count()).start();
		new Thread(new Count()).start();
		new Thread(new Count()).start();
	}
	
}
class Count implements Runnable{
	int count = 0;
	@Override
	public void run() {
		method2();
		}
		
	private synchronized void method2() {
		for (int i = 0; i < 100; i++) {
			count = i;
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			count--;
			System.out.println(Thread.currentThread().getName() + "::" + count);
		}
	}

		
	
}
就是把需要同步的语句放到一个函数中,然后把这个函数定义成synchoronized。这里使用的锁是this。也就是调用这个函数的对象的引用。需要注意的是,在静态方法中,使用的锁是类名.class。

九、死锁。死锁发生的原因是循环等待。也就是同步中嵌套同步,但是锁却不同。

死锁的示例:

class Deadlocker {
 int field_1;
 private Object lock_1 = new int[1];
 int field_2;
 private Object lock_2 = new int[1];

 public void method1(int value) {
  “synchronized” (lock_1) {
   “synchronized” (lock_2) {
    field_1 = 0; field_2 = 0;
   }
  }
 }

 public void method2(int value) {
  “synchronized” (lock_2) {
   “synchronized” (lock_1) {
    field_1 = 0; field_2 = 0;
   }
  }
 }
}
 






----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值