java中的线程

线程的一些基本概念

一,创建线程的方式
* 方式一:继承Thread类
* 步骤:
* 1.定义一个类继承Thread类
* 2.重写Thread类中的run 方法
* 3.直接创建Thread子类的对象
* 4.调用start方法开启线程并调用线程的任务run方法
*
*
* 可以通过Thread的getName获取线程的名称 Thread-编号(从0开始)
* 主线程的名字是main
* 可以通过Thread的currentThread方法 返回对当前正在执行的线程对象的引用
*
* 方式二:实现 Runnable接口
* 1.定义类实现 Runnable接口
* 2.重写接口的run方法,将线程的任务代码封装到run方法中
* 3.通过 Thread类创建线程对象,并将Runnable接口的子类对象作为构造函数的参数进行传递
*   为什么?
*   因为线程的任务都 封装在Runnable接口子类对象的run方法中
*   所以要在线程对象创建时就必须明确要运行的任务
*  4.调用线程对象的start方法开启线程
*
*  两种方式的区别:
*  方式二的好处:1.将线程的任务从线程的子类中分离出来 ,进行了单独的封装。将任务封装成对象
*                2.避免了java单继承的局限性
*
*   所以方式二较为常用

二,多线程中的一些线程安全问题 

线程安全问题出现的原因:
*   1.多个线程在操作共享的数据
*   2.操作共享数据 的线程代码有多余
*
*   当一个线程在执行操作共享数据的多条代码过程中,其它线程参与了运算,就会导致线程安全问题的产生
*
*   解决思路:
*   就是将多条操作共享数据的线程代码封装起来,当有线程在执行运算这些代码的时候 ,其它线程是不可以参与运算的
*   必须要当前线程把这些代码都 执行完毕 后,其它 线程才可以参与 运算。
*
*   在java 中,用同步代码块就可以解决这个问题
*   格式:
*   synchronized(对象){
*       需要被同步的代码
*   }
*  同步 的好处:解决了线程的安全问题
*         弊端:降低了效率,因为同步外的线程都会判断同步锁
*  同步 的前提 :同步中必须 有多个线程并使用同一个锁
*/


示例:

/**
 * 同步函数的使用的锁是  this
 * 同步函数和同步代码块的区别:
 * 同步函数的锁是固定的  this
 * 同步代码块的锁是任意的对象。
 *
 * 建议使用同步代码块,
 *
 *
   静态函数中因为没有this对象的引用,所以
 * 静态的同步函数使用的锁是 该函数所属字节码文件对象
* 可以用 getClass方法获取 ,也可以用当前 类.class获取

 
*/class Tichet implements Runnable{
private static int num = 100;
Object object = new Object();
boolean flg = true;
@Override

public void
run() {
 if (flg) {
 while (true) {
//注意 这里如果是静态的,则可以用 Tichet.class 或者 this.class
如果是非静态的,则可以直接用 this 

synchronized (Tichet.class) {//同步代码块
if (num>0){
 try {
  Thread.sleep(10);
 System.out.println(Thread.currentThread().getName()+"..obj..."+num--);
 } catch (InterruptedException e) {
 e.printStackTrace();
}
  }
  }
 }
 }else {
 while (true) {
 show();
 }
 }
 }
 public static synchronized void show(){//同步函数

 
if (num>0){
 try {
 Thread.sleep(10);
 System.out.println(Thread.currentThread().getName()+"..function..."+num--);
  } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }
}

public class SynFunctionLock {
  public static void main(String[] args){
 Tichet tichet = new Tichet();
        
        //这两种方式都是拿到当前对象的字节码文件
Class clas = tichet.getClass();
 Class classs = Tichet.class;
  Thread t1 = new Thread(tichet);
 Thread t2 = new Thread(tichet);
t1.start();
 try {
 Thread.sleep(10);
 System.out.println(Thread.currentThread().getName()+".....");
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
tichet.flg = false;
 t2.start();
}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值