java多线程

实现多线程的方式:使用一个类继承Thread使类成为一个线程类

                                 实现runnable接口重写run方法,将实现类的子类当target传入Thread(数据是可以共享的)(实现类可以继承)

线程的创建方式比较熟悉的是通过集成Runnable接口或者集成Thread类来实现,但是这两种方法都在线程执行完成后无法获取到执行结果,如果想异步执行某个任务并且执行完成之后需要知道他执行的结果的话可以使用Callable方式实现。

1实现callable接口实现call方法,call方法有返回值,再创建callable的实现类。

2使用futuretask对象包装callable对象,该对象封装了该callable对象的call方法返回值。

3使用futuretask对象的作为thread对象的target

4通过futuretask的对象的get方法获得子线程执行结束后的返回值。

使用start方法不会立即执行,可以在主线程里面加个sleep方法让主线程休息一毫秒,就行了。

其他线程与主线程有同样的地位,主线程结束其他线程不一定会结束。

public class CallableAndFuture {
    public static void main(String[] args) {
        Callable<Integer> callable = new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        };
        FutureTask<Integer> future = new FutureTask<Integer>(callable);
        new Thread(future).start();
        try {
            Thread.sleep(5000);// 可能做一些事情
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

 FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到.

join线程

让一个线程等待另一个线程完成的方法,当执行join时,调用的线程将被阻塞,直到join线程执行完为止。应用场景,将大问题划分成小问题,每个小问题分配线程,所有小问题得到处理后再调用主线程。

可通过setDaemon设置后台线程,必须在start之前,主线程结束,后台线程自动死亡。

sleep与yield方法区别

1.sleep方法执行后会给其他线程机会,不理会其他线程的优先级,但yield方法会给优先级相同或比他高的先执行。

2.sleep方法会将线程转为阻塞状态,yield则进入就绪状态

3.sleep抛出异常,yield方法不抛出任何异常

synchronize同步代码块,格式synchronize(obj){}含义:线程在执行同步代码块之前,必须获得同步监视器的锁定。通过这种方式可以进入修改共享资源的代码区又称临界区,同一时刻只有一个线程处于临界区内。静态方法的话用的是该类的字节码文件。synchronize锁方法的锁为this。

同步锁,reentranlock锁获取锁对象,lock.lock然后unlock


public class deadlock extends Thread{
private boolean flag;


public  deadlock(boolean b){
	flag=b;
}
public void run(){
	if(flag){
		synchronized (lock.obja) {
			System.out.println("if obja");
			
		
		synchronized (lock.objb) {
			System.out.println("if objb");
		}
		}
	}else{
		synchronized (lock.objb) {
			System.out.println("else objb");
			
		
		synchronized (lock.obja) {
			System.out.println("else obja");
		}
		}
	}
}
}

生产者消费者部分代码

public class SetThread implements Runnable {

	private Student s;
	private int x = 0;

	public SetThread(Student s) {
		this.s = s;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (s) {
				//判断有没有
				if(s.flag){
					try {
						s.wait(); //t1等着,释放锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				if (x % 2 == 0) {
					s.name = "林青霞";
					s.age = 27;
				} else {
					s.name = "刘意";
					s.age = 30;
				}
				x++; //x=1
				
				//修改标记
				s.flag = true;
				//唤醒线程
				s.notify(); //唤醒t2,唤醒并不表示你立马可以执行,必须还得抢CPU的执行权。
			}
			//t1有,或者t2有
		}
	}
}

         必须为同一把锁

public class GetThread implements Runnable {
	private Student s;

	public GetThread(Student s) {
		this.s = s;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (s) {
				if(!s.flag){
					try {
						s.wait(); //t2就等待了。立即释放锁。将来醒过来的时候,是从这里醒过来的时候
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				System.out.println(s.name + "---" + s.age);
				//林青霞---27
				//刘意---30
				
				//修改标记
				s.flag = false;
				//唤醒线程
				s.notify(); //唤醒t1
			}
		}
	}
}

线程通信:使用同步监视器方法实现通信,显示使用condition通信,使用阻塞对象实现线程通信,

threadlocal

public class pool {
	public static ThreadLocal<Integer>  x=new ThreadLocal<Integer>(){
		protected Integer initialValue() {//匿名内部类初始化值,底层调用的是currentthread线程将自己属性与每一个线程绑定。
			return 200;
		};
	};
	
public static void main(String[] args) {
//	System.out.println(Thread.currentThread().getName()+"--"+x.get());
	new Thread(new myrunnable()).start();
	new Thread(new myrunnable()).start();
}


public static class myrunnable implements Runnable{
      public myrunnable() {
    	  x.set(20);
		System.out.println(Thread.currentThread().getName()+"--"+x.get());
	}
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+"--"+x.get());
		
	}
	
}
}

happenbefore指令重排,指代码执行顺序与预期不一致。

volatitle保证程序变量的可见性,对线程A修改后,后面的线程可以看到修改的数值。即进行修改后立即写入主内存,线程变量在读取的时候在主内存读而不是在缓存中读。各线程的工作空间彼此不可见,相互独立,在工作时虚拟机为每个线程分配工作空间,不仅包括线程内部的局部变量,也包括线程所需要的共享变量的副本。只保证数据的同步,不保证原子性。

public class pool {
  public static volatile int num=0;//不加volatitle永远不会停,加了之后数据立马共享
  public static void main(String[] args) {
	new Thread(new Runnable() {
		public void run() {
			while(num==0){}
		}
	}).start();
	try {
		Thread.sleep(1000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	num=11;
}
}

ReentrantLock可重入锁,底层是wait外加锁计数器维持。模拟锁代码。

public class Lock{
    boolean isLocked = false;
    Thread  lockedBy = null;
    int lockedCount = 0;
    public synchronized void lock()
            throws InterruptedException{
        Thread thread = Thread.currentThread();
        while(isLocked && lockedBy != thread){
            wait();
        }
        isLocked = true;
        lockedCount++;
        lockedBy = thread;
    }
    public synchronized void unlock(){
        if(Thread.currentThread() == this.lockedBy){
            lockedCount--;
            if(lockedCount == 0){
                isLocked = false;
                notify();
            }
        }
    }
}

使用锁

public class Count{
    Lock lock = new Lock();
    public void print(){
        lock.lock();
        doAdd();
        lock.unlock();
    }
    public void doAdd(){
        lock.lock();
        //do something
        lock.unlock();
    }
}

我们设计两个线程调用print()方法,第一个线程调用print()方法获取锁,进入lock()方法,由于初始lockedBy是null,所以不会进入while而挂起当前线程,而是是增量lockedCount并记录lockBy为第一个线程。接着第一个线程进入doAdd()方法,由于同一进程,所以不会进入while而挂起,接着增量lockedCount,当第二个线程尝试lock,由于isLocked=true,所以他不会获取该锁,直到第一个线程调用两次unlock()将lockCount递减为0,才将标记为isLocked设置为false。
jvm栈内存是线程独有的,堆内存是共享的。只有一个方法区(字符串常量,静态方法)。

内容概要:《绿色转型美丽乡村——汾渭平原地区低碳乡村案例集》由西安空气侠环保科技有限公司编写,北京市企业家环保基金会支持,聚焦汾渭平原地区乡村低碳发展的典型实践。报告梳理了国内外相关理论研究及政策背景,展示了中央与地方在低碳乡村发展方面的政策措施。通过五个典型案例,包括芮城县庄上村的“光储直柔”模式、铜川耀州区克坊村的“光伏+普惠金融”、浮山县臣南河村的循环经济模式、澄城县权家河村的“风光储一体化”以及麟游县紫石崖村的“光伏+生态养殖”,详细分析了这些案例的技术路线、项目成效、主要政策、典型经验和存在问题。报告总结了清洁能源在乡村低碳发展中的核心地位,强调了因地制宜发展策略的关键作用,并指出了多重效益综合追求的重要性。 适合人群:从事环保、农业、能源领域研究的专业人士,以及关注乡村低碳发展和可持续发展的政策制定者和社会学者。 使用场景及目标:①为全国其他地区开展乡村能源转型实践提供有益的借鉴;②助力推动我国乡村低碳发展,为实现碳达峰、碳中和目标贡献积极力量;③为政策制定者提供决策参考,促进乡村绿色转型和乡村振兴战略的实施。 其他说明:报告由多家单位参编,感谢北京市企业家环保基金会提供资金支持。文中内容及意见仅代表作者的个人观点,与北京市企业家环保基金会的立场或政策无关。报告期望为全国其他地区开展乡村能源转型实践提供有益的借鉴,助力推动我国乡村低碳发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值