多线程系列(一)

获取当前线程的名称有以下方法:
Thread.currentThread().getName();
可以通过setName()对线程进行定义名称,通过getName()来获取名称;或者可以通过再构造函数中调用super(name)来获取定义好的线程名称;
线程都有自己的默认名称,一般是Thread 加编号,编号一般从0开始;

二: 售票程序例子,多个窗口买票
class Tiket extends Thread
{
  private static int tiketCount = 100;
//1:如果就是int,那么有多少线程去卖,就会卖多少线程数乘以100数;
//2:如果是static ,能控制统一卖100张,但是static的周期太长,性能不好; private static int tiketCount=100;
//这种方式创建线程不靠谱,解决方法,采用第2中方式来解决,就是implements  Runnable接口来实现;

 public void run(){
while(true){
  if(tiketCount>0){
  System.out.println(currentThread().getName+"tiket"+tiketCount-- );
}
}
}
}

public class TiketMain{

public static void main(String args[]){

Tiket tiket1 =new Tiket();
Tiket tiket2 =new Tiket();
Tiket tiket3 =new Tiket();
Tiket tiket4 =new Tiket();
tiket1.start();
tiket2.start();
tiket3.start();
tiket4.start();
}
}


2:实现方式二步骤
a:编写实现Runnable接口类;
b:重写Runnable接口的run方法;
c:通过Thread类建立线程对象;
d:将Runnable子类的实例对象作为Thread构造函数的参数,建立与Thread和Runnable子类的联系;
e:调用start方法启动线程,并调用Runnable接口的run方法,那么前面那个票数就不需要定义为static,多少个Thread对象类就会分配这个票数;


class Titket  impements Runnable{
 void run{}
}

public class TitketMain {

public static void main(String args[]){
 Titket titket = new Titket();
Thread thread1= new Thread(titket);
Thread thread2 = new Thread(titket);
......
thread1.start();
thread2.start();
 }
}


接口方法不能用throws抛出异常,如果抛出异常,程序就会runtime,终止运行,只能通过try、catch方式来捕获异常;
多线程程序中最重要的问题是,多个线程同时共享一个资源的时候,会出现线程安全问题,通过使用同步代码块来进行处理:
class titket implements Runnable{
private int titketCount= 100;
Object obj =new Object();
public void run(){
while(true){
  Synchronized(obj){
if(titketCount>0){
   
   try{Thread.sleep(10);}catch(Exception ex){}
   System.out.println(currentThread.getName+"titket run"+titketCount --);
        }
      }
   }
}


同步的经典例子----火车车厢中的WC;
同步的条件:
1:必须具备两个或两个以上的线程存在;
2:两个以上的线程同时共享一个资源,使用同一个锁;

三:多线程的线程安全
1:如何找出问题;
a:明确哪些代码是多线程运行代码;
b:明确共享数据;
c:明确多线程运行代码中那些是操作共享数据的;

class Bank
{
private int sum;
Object obj = new Object();
public void add(int n)throws Exception{
 Synchronized(obj){
   sum = sum+n;
   Thread.sleep(10);
  System.out.println("sum="+sum);
   }
 }
}

class Cus implements Runnable{
 Bank bank = new Bank();
 public void run(){
   for(int x=0;x<3;x++){
    try{
   bank.add(100);
   }catch(Exception ex){
    }
    }
  }
}

public class CusMain{
public static void main(String args[]){
Cus cus = new Cus();
Thread thread1 = new Thread(cus);
Thread thread2 = new Thread(cus);
....
 }
}


同步有两种表现方式:同步代码块和同步函数
以上代码如果需要更改成同步函数来完成,代码如下:
class Bank
{
private int sum;
//Object obj = new Object();
public Synchronized     void add(int n)throws Exception{
 //Synchronized(obj){
   sum = sum+n;
   Thread.sleep(10);
  System.out.println("sum="+sum);
  // }
 }
}

在程序运行中,如果需要暂停下main方法中的主线程,可以通过Thread.sleep(10);来实现;同步函数锁的对象是this,当前对象,如果使用同步代码块和同步函数同时使用,但是锁的对象不是同一个对象,那么肯定会存在问题。

四:多线程-静态同步函数的
如果同步函数被static修饰后,使用的锁是什么呢?
通过发现,对象不再是this,因为静态方法中也不可以定义this;

静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,类名.class,该对象的类型为class;
静态同步函数锁也是字节码文件对象,类名.class,该对象的类型也是为class。
通过同步代码更改为如下:
class Bank
{
private int sum;
//Object obj = new Object();
public void add(int n)throws Exception{
 Synchronized(Bank.class){  //匹配下面static 同步函数
   sum = sum+n;
   Thread.sleep(10);
  System.out.println("sum="+sum);
   }
 }

public static Synchronized show(){     //也是对应于Bank.class
..........................
  }
}


五:day11-14-多线程  多线程-单例设计模式-懒汉式
1:饿汉式
class Single{
private static final Single s = new Single();
public Single(){}
public static Single  getInstance(){
  return s;
   }
}
2:懒汉式
class Single{
 private static Single s = null;
 public Single(){}
 public static Single getInstance(){
  if(null == s){
    s = new Single();
   return s;
  }
 }

懒汉式也叫延迟加载,例如if(null == s){    s = new Single();
如果是多线程同时共享懒汉式,就会执行  new  Single()对象很多次,解决办法如下:
 public static Synchronized  Single getInstance(),不过没个线程进来都需要判断下,懒汉式同步性能是最低效的,不建议使用;
不过用双重否判断可以解决,一般都采用饿汉式单例模式,修改语句如下:

class Single{
 private static Single s = null;
 public Single(){}
 public static Single getInstance(){
    if(null == s){
      Synchronized(Single.class){
               if(null == s){
                    s= new Single();
                }
         }
     }
   }
}

六:day11-15-多线程(多线程-死锁)
死锁:同步中嵌套同步,但是锁却不同;机器不同,有可能这台机出现死锁,其它机不重现死锁情况,可以通过whrte(true)来发现排除。有可能出现和谐状态,就不会发现死锁情况。
Class Cou{
Object a = new Object();
Object b = new Object();
}

class  ThreadTest  implements Runnable{
 Cou cou = new Cou();
  private boolean flag;
   public void run(){
    if(flag){
        Synchronized(cou.a){
                      Synchronized(cou.b){
                         }
                  }
           }else{
          Synchronized(cou.b){
                     Synchronized(cou.a){
                        }
               }
        }
   }
 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tony168hongweigan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值