【Java多线程】学习日记

一、创建方式

1. 实现runable接口
步骤:1.创建类实现runable接口重写run方法
2.建立类的实例对象
3.将实例对象放在new thread中
4.调用thread类中start方法调用run方法

public class textrunable {
	public static void main(String[] args) {
		/*
		//创建实现类对象
		B b=new B();
		//创建实现代理对象
		Thread ss=new Thread(b);
		ss.start();
		*/
		new Thread(new B()).start();//匿名对象与上述所实现用法相同
		for(int i=0;i<20;i++) {
			System.out.println("I am a hero");
		}	
	}
}
class B implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<20;i++) {
			System.out.println("you are a foolish");
		}
	}
}

2. 继承Thread类(是runable接口的实现类)
步骤:1.创建类继承thread类重写run方法
2.建立类的实例对象
3.调用start方法运行

public class textthread {
	public static void main(String[] args) {
		A a=new A();
		a.start();
		for(int i=0;i<20;i++) {
			System.out.println("eat fish");
		}	
	}
}

class A extends Thread{
	
	public void run() {
		for(int i=0;i<20;i++) {
			System.out.println("study");
		}
	}
}

3. 实现callable接口
步骤:1.创建类实现callable接口并重写all类(此方法与run不同可以有返回值)
2.建立实例对象
3.放到futuretask()中
4.使用new thread。start启动线程

ublic class CallableTest {
    public static void main(String[] args) {
        test0 test0=new test0();
        FutureTask<Integer> f = new FutureTask<>(test0);
        new Thread(f).start();

        try {
            /*此方法可以得到call方法内的返回值*/
            Integer integer = f.get();
            System.out.println(integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
    
}
class test0 implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {  
        int sum=0;
        for (int i=0;i<10;i++){
            sum+=i;
        }
        return sum;
    }
}

4. 使用线程池
方法如下

public class ThreadPool {
    public static void main(String[] args) {
        /*建立一个线程池*/
        ExecutorService service = Executors.newFixedThreadPool(10);
        /*创建实例*/
        test1 test1 = new test1();
        /*执行提交*/
       service.execute(test1);
       service.submit(new test2());
        /*关闭线程池*/
        service.shutdown();
    }
}

class test1 implements Runnable {
    
    @Override
    public void run() {
        //int sum=0;
        for (int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}

class test2 implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {

        int sum=0;
        for (int i=0;i<10;i++){
            System.out.println(sum+=i);
        }
        return sum;
    }
}
  

二、线程同步

1. synchronized代码块
如果是代码块的形式 继承thread 那么这个this类 不是一个唯一的对象所以锁不住需要调用 this.class使用它的类锁住 而第二种实现runable接口则只创建了一个对象所以说this是一个唯一对象就可以锁住
synchronized代码块的基本使用,以下便不一一列举了。

public class textCynchronized {
	public static void main(String[] args) {
		t12306 tt=new t12306();		
		new Thread(tt,"1号").start();
		new Thread(tt,"2号").start();
	}

}
class t12306 implements Runnable{
	private int tackit=10;
	private boolean flag=true;
	@Override
	public void run() {
		while(flag) {
			stop();
		}
		return;
	}
	public void stop() {
		synchronized (this) {
		if(tackit<=0) {
			flag=false;
		}
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("取票人"+Thread.currentThread().getName()+"--->"+tackit--);
	}
		}
	
	
}

2. synchronized方法
使用同步方法也需要主要上面所强调的this对象是否唯一的问题 因为同步方法 使用synchronize关键字默认 使用的锁对象(唯一对象)就是this ,这是使用实现runable接口的方式创建没用问题,但是要是继承thread的方式创建仍然是线程不安全,你需要在方法上加static关键字这就使得上升到了类的层面所以就符合了唯一对象的局限性
3. 建立lock实例
首先在你要保证线程安全的类中建立一个lock类用于实现线程的安全问题,以上所述lock是一个接口需要建立他的实例需要用它的实现类比如ReentrantLock用于建立对象,此时他所获得的锁仍然是this对象,所以必须只有一个实例,使用lock方法获得锁,使用unlock方法解除锁,此方法使锁定的范围设置变得更加灵活。
4. 线程的通信(必须建立在synchronized代码块或synchronized方法中使用)
线程的通信主要使用阻塞方法:wait()(此方法在执行时会释放当前锁,也就是synchronized中的锁),通知解除阻塞的方法:notify(),notifyAll()。
以上三个方法并不是thread中的方法,而是object中的方法。意思就是任何一个对象都可以调用。
通过这样通信阻塞的方法就可以实现线程的交互。

以下是一个线程安全的简单例子

public class test {
    public static void main(String[] args) {
        Access ass = new Access();
        Custorm no1 = new Custorm(ass, 1000, null, true);
        Custorm no2 = new Custorm(ass, 1000, null, true);
        Thread thread = new Thread(no1);
        Thread thread1 = new Thread(no2);

        thread.start();
        thread1.start();
        
    }
    
}

class Custorm implements Runnable{
    private Access access;
    private Integer savecount;
    private Integer outcount;
    private boolean flag;

    public Custorm(Access access, Integer savecount, Integer outcount, boolean flag) {
        this.access = access;
        this.savecount = savecount;
        this.outcount = outcount;
        this.flag = flag;
    }
    
    public  void savemoney(){
        synchronized (access){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            access.setMoney(access.getMoney()+savecount);
            System.out.println(Thread.currentThread().getName()+"存入"+this.savecount+"余额为:"+access.getMoney());
        }
       
    }
    public  void outmoney() {
        
        if (access.getMoney()>outcount){
            System.out.println(Thread.currentThread().getName()+"取出"+this.outcount+"余额为:"+access.getMoney());
            access.setMoney(access.getMoney()-outcount);
        }else {
            System.out.println("余额不足");
        }
    }

    @Override
    public void run() {
        for (int i = 0; i <= 6; i++) {
            if (flag) {
                savemoney();
            } else {
                outmoney();
            }
        }
    }
}

class Access{
    private Integer money=3000;

    public Access() {
    }

    public Integer getMoney() {
        return money;
    }

    public void setMoney(Integer money) {
        this.money = money;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值