第十一天总结0403

第十一天总结
1.同步synchronized
sleep方法是静态的,可以直接用类名Thread调用,此方法被抛出异常了,所以我们要处理一下,try.catch,因为在多线程中,我们覆盖的是Runnable中的方法,所以不能直接在函数上抛出

,而是要处理掉。
……………………………………………………………………………………
同步的第一种方式:
同步代码块:
synchronized(对象)
{
 需要同步的代码
}
synchronized后面跟的对象是任意的对象,其实这个对象就是一个锁,当某个线程进入同步代码块中,就会把锁置为关,所以外面的线程是进不来的,而只有当该线程把同步代码块的所有数

据读完了之后出同步的时候才会把锁置为开,接下来后面的线程才能进到同步中继续运行,这个锁就叫监视器锁。
同步的弊端就是相对耗费计算机资源
同步的前提:a/同步需要两个或两个以上的线程,b/多个线程使用的是同一个锁
同步也可以说是将需要同步的代码进行了一种封装,一种加了锁的封装
……………………………………………………………………………………
同步的第二种方式:
同步函数:
只要将synchronized作为函数的的一个修饰符就可以做为同步函数了
同步不要放到run方法上,因为放在了run方法上,如果里面有循环,那么只要循环不结束,同步在里面的线程就不会出来,外面的线程进不去,很消耗计算机资源。
同步代码块和同步函数的区别:
同步代码块的锁可以使任意的类所属的对象
而同步函数的锁是this锁,只有这唯一的一个
那么同步代码块的扩展性明显要好
在学习单例设计方式的时候,我们分析了第二种设计方式存在安全性问题,在这里可以用同步来解决
class Single
{
 private static Single s=null;
 private Single(){}
 public static synchronized Single getSingle()
 {
  if(s==null)
 /*
 如果多线程访问该方法,容易出现线程安全问题,不能再保证对象的唯一性,所  以要对该方法进行同步,但是同步的出现会有一些弊端,相对消耗资源。
 */
  {
   s=new Single();
  }
  return s;
 }
}
……………………………………………………………………………………
2.线程间通信
所要处理的资源是一样的,可是每一个线程的处理方式却不一样
两段代码在循环中切换的一种方式:
while(true)
{
int x=0
if(x==0)
{
code a------
}
else
code b------
x=(x+1%)2
}
……………………………………………………………………………………
线程操作方法
wait等待方法
notify唤醒方法
notifyAll唤醒全部方法
这些方法都要放到同步当中,而且他们都有异常抛出,所以要进行处理
只有在同一个代码块中才能使用wait和notify,必须要表示出这两个方法所属的同步代码块,也就是要用锁标示,而且这两个方法是成对出现的
给wait这类方法标示的是锁,而同步代码块的锁是任意对象,所以任意对象都可以给wait标示,而任意对象所属的类都是object的子类,所以这类方法都在object中
千万要注意死锁,通常出现在同步的嵌套中,A锁的当中有B锁,B锁的当中有A锁,就很容易出现死锁,尽量不要写嵌套,如果真要嵌套,一定要注意锁的顺序
……………………………………………………………………………………
wait和sleep的区别:
wait冻结线程的时候不仅释放计算机资源,也释放锁
sleep冻结线程的时候仅仅释放计算机资源,不释放锁
在写同步的时候一定要注意两点:1是注意计算机资源的消耗2是注意不能出现死锁
……………………………………………………………………………………
3.线程的停止
interrupt中断线程方法
//如果在线程中调用了wait等控制线程的方法的时候,此时线程被冻结了,那么这个时候//我们可以用interrupt方法来清除冻结状态,让线程继续运行下去直到结束
//当interrupt在清除冻结状态的时候,还会出现一个异常,所以要处理
停止线程的两种方式:
a定义结束标记,原理:通常在run方法中我们都要写循环,所以我们可以通过控制循环来控制线程。只要循环结束了,那么线程也就结束了。
但是如果在run中,线程处于冻结状态了,连标记都读不到,所以这种方法就不行了
b中断线程(interrupt):强制结束线程的冻结状态,让其恢复到运行中来;
注意的是强制结束冻结状态会发生InterruptedException异常,要进行处理
……………………………………………………………………………………
4.线程中的其他方法
toString()方法,返回该线程的字符串表现形式,他包括线程名称,优先级和线程组
优先级一共定义可十个值,以至于区分开来,但是比如说3,4的区别并不大吗,所以优先级区分最大的是1,5,10,
Thread.MAX_PRIORITY线程中的最高优先级,输出的时候是数字10表示
Thread.MIN_PRIORITY线程中的最低优先级,输出的时候是1表示
Thread.NORM_PRIORITY线程中的默认优先级,输出的时候是5表示
优先级是静态的最终化的一个常量
setPriority()设置优先级方法
getPriority()获取优先级的方法
优先级越高的话,抢到资源的几率就越高
………………………………………………
setDaemon()该线程标记为守护线程或用户线程(后台线程)这个方法上要是一个条件
sttDaemon(true)就转换成后台,如果里面是false,就不转换
这个方法必须在线程启动前调用
在没有被这个方法标记之前,所开启的都是前台线程,后台线程在开启的时候也和前台线程一样的抢资源,但是只要当前台线程一结束,后台线程不管在做什么都会立马结束消失,当没有前

台线程的话,JVM就立即退出。
………………………………………………
Thread类提供了构造函数,可以给线程取名字
当时实现的方式创建的线程的时候,在建立对象的时候可以直接传一个进去
当是继承的方式创建的线程的时候,我们可以在继承类中的构造函数中加super(name);
………………………………………………
join()加入方法,等待线程终止(等待这个线程去死)
join方法在使用的时候有异常抛出,所以在使用的时候要用try.catch处理
x.join()的通俗解释就是,当这个方法出现的时候,只有等到x所在的这个线程结束后其他的线程才能开始运行,但是此时的计算机资源不一定全部都是x的。但是只要x线程读完的时候,join

后面的线程才会开始运行。
join可以用在临时插入线程的时候
………………………………………………
yield()暂停当前正在执行的线程对象,并执行其他的线程,意思就是让当前线程释放计算机资源,只是稍微延缓一下
………………………………………………
当多部分代码被同时执行的时候,我们就要想到用多个控制单元来分别执行这些代码,就要想到用多线程来实现。
………………………………………………


/*
需求:建立一个人的资源,资源的属性包括名字和性别
 要求用一个线程对该资源的属性进行输入
 要求用一个线程对该资源的属性进行打印输出
 以下是优化后的代码
*/
class Res//建立一个资源类
{
 private String name;
 private String sex;
 private boolean b;//用于表示人这个资源中是否有属性,默认为假
 public synchronized void set(String name,String sex)
 {
  if (b)
  {
   try
   {
    this.wait();
   }
   catch (Exception e)
   {
   }
  }
   this.name=name;
   this.sex=sex;
   b=true;
   this.notify();
 }
 public synchronized void method()
 {
  if (!b)
  {
   try
   {
    this.wait();
   }
   catch (Exception e)
   {
   }
  }
   System.out.println(this.name+"---------"+this.sex);
   b=false;
   this.notify();
 }

}
class InPut implements Runnable//建立输入类实现接口
{
 Res r;//建立一个资源对象的引用
 InPut(Res r)//构造函数初始化
 {
  this.r=r;
 }
 public void run()//实现接口中的run方法
 {
  int x=0;
  while (true)
  {
   if (x==0)
   {
    r.set("mike","men");
   }
   else
   {
    r.set("云云","女");
   }
   x=(x+1)%2;//作用是让x不断在0和1之间交替,从而使if和else在交替执行
  }
 }
}
class OutPut implements Runnable//定义一个输出类实现接口
{
 Res r;
 OutPut(Res r)
 {
  this.r=r;
 }
 public void run()
 {
  while (true)
  {
   r.method();
  }
 }
}
class ResDemo2
{
 public static void main(String[] args)
 {
  Res r=new Res();
  new Thread(new InPut(r)).start();
  new Thread(new OutPut(r)).start();
 }
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值