黑马程序员-多线程

---------------------- Android培训java培训、期待与您交流! ----------------------

java多线程:

进程:是一个正在执行的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。一个进程中至少有一个线程。

 

java创建线程的方式:

一、继承Thread类

1,定义类继承Thread。

2,复写run方法(目的是将自定义代码存储在run方法中供线程执行。)

3,调用start()方法(start方法有两个作用,一是启动线程,二是调用run方法。)

二、实现Runnale接口

1,定义类实现Runnable接口。

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

3,通过Thread类建立线程对象。

4,将实现Runnable接口的子类对象,作为实际参数传递给Tread类的构造方法。

5,调用Tread类的start方法。

 

锁机制(同步代码块):

java对于多线程的安全问题提供了专业的解决办法,即同步代码块。

格式:

synchronized(对象)

{

需要被同步的代码。

}

同步的功能:

第一个进入同步代码块的线程将持有锁,只有持有对象锁的线程才可以在同步中执行,在该线程执行期间其他线程无法执行同步中的代码。

同步的前提:

1,要有两个或两个以上的线程。

2,多个线程必须使用的是同一把锁。

注:

1,同步函数使用的锁是this。public synchronized void show(){}

 2,静态的同步函数使用的锁是该类的字节码文件对象。

 

单例设计模式:

//懒汉式
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 single{
private static Single s = new Single();
private Single(){}
public static Single getInstance(){
return s; 
}
}


死锁问题:

多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

同步代码块的嵌套很容易导致死锁。

//死锁小程序一个
class MyLock{
public static Object locka = new Object();
public static Object lockb = new Object();
}
class Test implements Runnable{
private boolean flag;
Test(boolean flag){
this.flag = flag;
}
public void run(){
if(flag){
 while(true){
 sychronized(MyLock.locka){
  System.out.println(Thread.currentThread().getName()+"---locka");
  synchronized(MyLock.lockb){
   System.out.println(Thread.currentThread().getName()+"---lockb");
  }
 }
 }
}else{
 while(true){
 sychronized(MyLock.lockb){
  System.out.println(Thread.currentThread().getName()+"---lockb");
  synchronized(MyLock.locka){
   System.out.println(Thread.currentThread().getName()+"---locka");
  }
 }
 }
}
}
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();
}


等待唤醒机制:

wait():线程等待。

notify():唤醒当前锁上等待的单个线程,最早等待的最早被唤醒。

notifyAll():唤醒当前锁上等待的所有线程。

注:

1,以上3个方法都使用在同步中。

2,等待和唤醒必须是同一个锁。

3,锁可以是任意对象,所以3个方法都定义在Object类中。

 

生产者消费者问题:

class Resource{
private String name;
private int count = 1;//标识生产产品的个数。
private boolean flag = false; //标识Resource中是否有产品。
public synchronized void set(String name){
while(flag) //用While让唤醒的线程再次判断标记,以免重复生产。
 try{this.wait();}catch(Exception e){}
this.name = name+"---"+count++;
System.out.println(Thread.currentThread().getName()+"生产"+this.name);
flag = true;
this.natifyAll(); //单纯使用notify只唤醒生产者线程,容易造成线程全部等待
}

public synchronized void out(){
while(!flag)
 try{this.wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"消费"+this.name);
flag = false;
this.notifyAll();
}
}
class Producer implements Runnable{
private Resource res;
Producer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.set("+商品+");
}
}
}
class Consumer implements Rnnnable{
private Resource res;
Consumer(Resource res){
this.res = res;
}
public void run(){
while(true){
res.out();
}
}
class ProducerConsumerDemo{
public static void main(String[] args){
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}


停止线程:

stop()方法已过时,想要停止线程只有一种方式。即run方法结束。

守护线程:

Thread类中setDaemon()方法可以将线程标记为后台线程或用户线程。当正在运行的线程都是守护线程时,jvm退出。该方法在启动线程调用。

join方法:

当A线程执行到B线程的join方法时,A就会等待B线程执行完,A才执行。join可以用来临时加入线程。

线程优先级:

Thread的toString方法返回线程的字符串形式,包括线程的名称,优先级看,线程组。

所有线程优先级默认为5.(1~10)

setPriority()方法可以改变线程优先级。

Thread类中优先级静态字段:

MAX_PRIORITY = 10;

MIN_PRIORITY  = 1;

NORM_PRIORITY = 5;

 

 yield()方法(static):

暂停当前线程,减少线程执行频率,起到均衡每个线程执行次数的效果。

 

内部类方式创建线程:

//方式1
new Thread(){
public void run(){
 for(int x=0; x<100; x++){
  System.out.println(Thread.currentThread().getName()+"---"+x);
 }
}
}.start();

//方式2
Runnable r = new Runnable(){
public void run(){
 for(int x=0; x<100; x++){
  System.out.println(Thread.currentThread().getNmae()+"---"+x);
 }
}
}
new Thread(r).start();



 

 

 

 

 

 

 

 

 

---------------------- Android培训java培训、期待与您交流! ----------------------

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值