ThreadLocal

P3141_7_2_14_匿名内部类方式实现线程的创建
P3171_7_3_03_线程安全问题举例解析(比如,为何三个线程都抢到第100张票(抢票和票–,执行有时间差,在这个差里,其他两个线程都抢票了,但是第一个抢票的线程还未到–,有点像脏读的意思。为何会有负的:第一个出来后判断条件不符合,正常已不进去,但方法的局部代码块里还有行程在待醒,比如第二第三个线程睡醒了,又去抢票,又–,那么,就有负了(而且,三个线程,最多最蛋疼最坏情况也就是最终票数会到-1了)))
327线程间通信
332线程池
https://www.bilibili.com/video/av54059237/?p=314

Java线程的5种状态及切换
https://www.cnblogs.com/hejing-swust/p/8038263.html

1. 新建(NEW):新创建了一个线程对象。
2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
3. 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4. 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 
(). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
5. 死亡(DEAD):线程run()main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

java中创建线程的三种方法以及区别
https://www.cnblogs.com/3s540/p/7172146.html

java中线程同步的几种方法
https://blog.csdn.net/scgyus/article/details/79499650
方法一:
使用synchronized关键字 (修饰方法,就叫同步方法)
方法二:
wait()和notify()
sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
sleep()方法导致了程序暂停执行指定的时间,让出抢到的cpu的执行权,给其他线程抢,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,(如果有锁的话),线程不会释放对象锁(只是“睡眠”,不放锁,而且还定时,时间到了就恢复运行)(那其他抢到执行权的线程,却无法操作那个有锁的对象(比如runnableImpl))。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。(放了锁,滚回大部队,和大部队一起等待,被允许了(不然就还是在挂起状态),才能有下一次争锁的机会,争到了锁才能运行)

方法三:
使用特殊域变量volatile实现线程同步
方法四:
在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。
ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。
方法五:
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。
方法六:
使用阻塞队列实现线程同步
方法七.
使用原子变量实现线程同步

面试题:线程池、核心线程数、最小线程数
线程间通信:不同任务的线程操作同一个对象,合作/协作/协同/同步?完成一个整个一个事儿的时候(官方:多个线程在处理同一个资源,但是处理的动作(线程的任务),却不相同)。(生产者消费者例子)。通过等待唤醒机制。
线程池(即一个线程的容器):因为线程创建和销毁需要时间,如果一件事需要大量并发线程且每个线程很短时间就完成任务了,为了避免大量运行时间耗费在创建和销毁(避免过多消耗资源),即为了实现线程的复用(不销毁,接着用(执行其他任务)),可以使用线程池技术。容器推荐用LinkedList(底层链表,线程安全)。
JAVA基础:ArrayList和LinkedList区别
https://www.cnblogs.com/showme1942/p/10059559.html
【目前有一个想法,把线程技术作为自己的招牌】
P334 lambda编程:函数式编程思想,只关注()→{}就完事了

浅谈ThreadLocal
https://zhuanlan.zhihu.com/p/60375306

ThreadLocal项目案例
https://zhuanlan.zhihu.com/p/60665911

线程安全练习-经典:生产者消费者
原文:生产者/消费者问题的多种Java实现方式
https://blog.csdn.net/monkey_d_meng/article/details/6251879
仓库:

import java.util.LinkedList;
/**
 * 仓库类Storage实现缓冲区
 */
public class Storage
{
	// 仓库最大存储量
	private final int MAX_SIZE = 100;
	// 仓库存储的载体
	private LinkedList<Object> list = new LinkedList<Object>();
	// 生产num个产品
	public void produce(int num)
	{
		// 同步代码段/块
		synchronized (list)
		{
			// 如果仓库剩余容量不足
			while (list.size() + num > MAX_SIZE)
			{
				System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:"
				        + list.size() + "/t暂时不能执行生产任务!");
				try
				{
					// 由于条件不满足,生产阻塞
					list.wait();
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
			// 生产条件满足情况下,生产num个产品
			for (int i = 1; i <= num; ++i)
			{
				list.add(new Object());
			}
			System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size());
			list.notifyAll();
		}
	}

	// 消费num个产品
	public void consume(int num)
	{
		// 同步代码段
		synchronized (list)
		{
			// 如果仓库存储量不足
			while (list.size() < num)
			{
				System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:"
				        + list.size() + "/t暂时不能执行生产任务!");
				try
				{
					// 由于条件不满足,消费阻塞
					list.wait();
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}

			// 消费条件满足情况下,消费num个产品
			for (int i = 1; i <= num; ++i)
			{
				list.remove();
			}
			System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size());
			list.notifyAll();
		}
	}

	// get/set方法
	public LinkedList<Object> getList()
	{
		return list;
	}

	public void setList(LinkedList<Object> list)
	{
		this.list = list;
	}

	public int getMAX_SIZE()
	{
		return MAX_SIZE;
	}
}

生产者:

/**
 * 生产者类Producer继承线程类Thread
 */
public class Producer extends Thread
{
	// 每次生产的产品数量
	private int num;

	// 所在放置的仓库
	private Storage storage;

	// 构造函数,设置仓库   //这么写,到时候,符合开闭原则(如果Storage是个接口,你到时候是需要放实现类的话,你就能感受到了)
	public Producer(Storage storage)
	{
		this.storage = storage;
	}

	// 线程run函数
	public void run()
	{
		produce(num);
	}

	// 调用仓库Storage的生产函数
	public void produce(int num)
	{
		storage.produce(num);
	}

	// get/set方法
	public int getNum()
	{
		return num;
	}

	public void setNum(int num)
	{
		this.num = num;
	}

	public Storage getStorage()
	{
		return storage;
	}

	public void setStorage(Storage storage)
	{
		this.storage = storage;
	}
}

消费者:

/**
 * 消费者类Consumer继承线程类Thread
 */
public class Consumer extends Thread
{
	// 每次消费的产品数量
	private int num;

	// 所在放置的仓库
	private Storage storage;

	// 构造函数,设置仓库
	public Consumer(Storage storage)
	{
		this.storage = storage;
	}

	// 线程run函数
	public void run()
	{
		consume(num);
	}

	// 调用仓库Storage的生产函数
	public void consume(int num)
	{
		storage.consume(num);
	}

	// get/set方法
	public int getNum()
	{
		return num;
	}

	public void setNum(int num)
	{
		this.num = num;
	}

	public Storage getStorage()
	{
		return storage;
	}

	public void setStorage(Storage storage)
	{
		this.storage = storage;
	}
}

测试类:

/**
 * 测试类Test
 */
public class Test
{
	public static void main(String[] args)
	{
		// 仓库对象
		Storage storage = new Storage();

		// 生产者对象
		Producer p1 = new Producer(storage);
		Producer p2 = new Producer(storage);
		Producer p3 = new Producer(storage);
		Producer p4 = new Producer(storage);
		Producer p5 = new Producer(storage);
		Producer p6 = new Producer(storage);
		Producer p7 = new Producer(storage);

		// 消费者对象
		Consumer c1 = new Consumer(storage);
		Consumer c2 = new Consumer(storage);
		Consumer c3 = new Consumer(storage);

		// 设置生产者产品生产数量
		p1.setNum(10);
		p2.setNum(10);
		p3.setNum(10);
		p4.setNum(10);
		p5.setNum(10);
		p6.setNum(10);
		p7.setNum(80);

		// 设置消费者产品消费数量
		c1.setNum(50);
		c2.setNum(20);
		c3.setNum(30);

		// 线程开始执行
		c1.start();
		c2.start();
		c3.start();
		p1.start();
		p2.start();
		p3.start();
		p4.start();
		p5.start();
		p6.start();
		p7.start();
	}
}


---------------------------控制台打印提示语---------------------------------
运行结果,控制台打印:
【要消费的产品数量】:50	【库存量】:0	暂时不能执行生产任务!
【要消费的产品数量】:30	【库存量】:0	暂时不能执行生产任务!
【要消费的产品数量】:20	【库存量】:0	暂时不能执行生产任务!
【已经生产产品数】:10	【现仓储量为】:10
【要消费的产品数量】:20	【库存量】:10	暂时不能执行生产任务!
【要消费的产品数量】:30	【库存量】:10	暂时不能执行生产任务!
【要消费的产品数量】:50	【库存量】:10	暂时不能执行生产任务!
【已经生产产品数】:10	【现仓储量为】:20
【要消费的产品数量】:50	【库存量】:20	暂时不能执行生产任务!
【要消费的产品数量】:30	【库存量】:20	暂时不能执行生产任务!
【已经消费产品数】:20	【现仓储量为】:0
【已经生产产品数】:10	【现仓储量为】:10
【已经生产产品数】:10	【现仓储量为】:20
【已经生产产品数】:80	【现仓储量为】:100
【要生产的产品数量】:10	【库存量】:100	暂时不能执行生产任务!
【已经消费产品数】:30	【现仓储量为】:70
【已经消费产品数】:50	【现仓储量为】:20
【已经生产产品数】:10	【现仓储量为】:30
【已经生产产品数】:10	【现仓储量为】:40

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蛋白质是生物体中普遍存在的一类重要生物大分子,由天然氨基酸通过肽键连接而成。它具有复杂的分子结构和特定的生物功能,是表达生物遗传性状的一类主要物质。 蛋白质的结构可分为四级:一级结构是组成蛋白质多肽链的线性氨基酸序列;二级结构是依靠不同氨基酸之间的C=O和N-H基团间的氢键形成的稳定结构,主要为α螺旋和β折叠;三级结构是通过多个二级结构元素在三维空间的排列所形成的一个蛋白质分子的三维结构;四级结构用于描述由不同多肽链(亚基)间相互作用形成具有功能的蛋白质复合物分子。 蛋白质在生物体内具有多种功能,包括提供能量、维持电解质平衡、信息交流、构成人的身体以及免疫等。例如,蛋白质分解可以为人体提供能量,每克蛋白质能产生4千卡的热能;血液里的蛋白质能帮助维持体内的酸碱平衡和血液的渗透压;蛋白质是组成人体器官组织的重要物质,可以修复受损的器官功能,以及维持细胞的生长和更新;蛋白质也是构成多种生理活性的物质,如免疫球蛋白,具有维持机体正常免疫功能的作用。 蛋白质的合成是指生物按照从脱氧核糖核酸(DNA)转录得到的信使核糖核酸(mRNA)上的遗传信息合成蛋白质的过程。这个过程包括氨基酸的活化、多肽链合成的起始、肽链的延长、肽链的终止和释放以及蛋白质合成后的加工修饰等步骤。 蛋白质降解是指食物中的蛋白质经过蛋白质降解酶的作用降解为多肽和氨基酸然后被人体吸收的过程。这个过程在细胞的生理活动中发挥着极其重要的作用,例如将蛋白质降解后成为小分子的氨基酸,并被循环利用;处理错误折叠的蛋白质以及多余组分,使之降解,以防机体产生错误应答。 总的来说,蛋白质是生物体内不可或缺的一类重要物质,对于维持生物体的正常生理功能具有至关重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值