Thread2(多线程)再接再厉ヾ(◍°∇°◍)ノ゙

来源:互联网 发布:linux自动化部署工具 编辑:程序博客网 时间:2024/06/15 13:31

多线程小结:

1.多线程并发访问同一段资源,会形成抢的现象,由于线程切换的时机不确定,可能会导致执行代码顺序混乱,严重时会导致系统瘫痪。(取个豆子桌子还欠几百万)

2. 方法被synchronized修饰以后为同步方法,即多个线程不能同时进入方法内部执行。对于成员方法而言,synchronized会在线程调用该方法时将方法所属对象枷锁,其他线程在执行该方法时由于执行方法的线程没有释放锁,所以只能在方法外阻塞,直到持有方法锁的线程将方法执行完毕,所以解决多线程并发执行安全问题的办法就是变抢位排队。

3.同步块,有效的缩小同步范围可以保证并发安全的同时,提升并发的效率。(逛商场大家一起逛,试衣间排队)

 同步块可以要求多个线程对该块内的代码排队执行,但是前提是同步监视器对象(即上锁对象)要求多个线程看到的必须是同一个两个试衣间或者锁的是new Object()都不行,synchronized(同步监视对象){需要同步的代码}
所谓同步:多个线程必须排队执行
所谓异步:多个线程可以同时执行

4. 静态方法的同步:当一个静态方法被synchronized修饰以后,那么该方法即为同步方法,由于静态方法全局就一所以同步的静态方法一定具有同步效果和对象无关

5.互斥锁
synchronized也叫互斥锁,使用它修饰的多段代码,只要他们的同步监视器对象相同,那么这几段代码间就是互斥关系,即多个线程不能同时执行这些代码,关键是选取对象是一个,同步锁和互斥锁的差异,修饰的是否是同一段代码
,但是选取的对象一定是一个。

6.将集合或者Map转化为线程安全的,ArrayList 和LinkedList都不是线程安全的,API手册上有说明就算是线程安全的集合那么对于元素的操作,如add,remove等方法都不与迭代器遍历做互斥,需要自行维护互斥关系

7.线程池:控制线程数量,重用线程。当我们发现需要创建大量线程或者发现线程会频繁的创建或销毁时就应当考虑使用线程池来维护线程,4种创建方式:
 1.弹性的
 Executors.newCashedThreadPool();
   2.固定数量的
   Executors.newFixedThreadPool(n);
 3.可延迟定期执行的
   Executors.newScheduledThreadPool();
 4.单个线程
   Exeutors.newSingleThreadExecutor();

***************************************************************************************************************

取豆子欠了几百万.......

public class demo1 {
public static void main(String[] args) {
final Table table=new Table();
Thread t1=new Thread(){
public void run(){
while(true){
int bean=table.getBean();
Thread.yield();
System.out.println(getName()+":"+bean);
}
}
};
Thread t2=new Thread(){
public void run(){
while(true){
int bean=table.getBean();
Thread.yield();
System.out.println(getName()+":"+bean);
}
}
};
t1.start();
t2.start();
}
}
class Table{
//桌子上有20个豆子
private int beans=20;
public synchronized int getBean(){
if(beans==0){
throw new RuntimeException("没有豆子了!");
}
Thread.yield();
return beans--;
}
}

***********************************************************************************************************

线程安全情况下减少时间

public class demo2 {
public static void main(String[] args) {
final Shop shop=new Shop();
Thread t1=new Thread(){
public void run(){
shop.buy();
}
};
Thread t2=new Thread(){
public void run(){
shop.buy();
}
};
t1.start();
t2.start();
}
}
class Shop{
public void buy(){
Thread t=Thread.currentThread();
try {
System.out.println(t.getName()+";正在挑衣服");
Thread.sleep(5000);
synchronized(new Object()){
System.out.println(t.getName()+";正在试衣服");
Thread.sleep(5000);
}
System.out.println(t.getName()+";结账离开");
} catch (Exception e) {
e.printStackTrace();
}
}
}

***********************************************************************************

synchronized修饰静态方法

public class demo3 {
public static void main(String[] args) {
final Foo f1=new Foo();
final Foo f2=new Foo();

Thread t1=new Thread(){
public void run(){
Foo.dosome();//跟对象无关
}
};
Thread t2=new Thread(){
public void run(){
Foo.dosome();
}
};
t1.start();
t2.start();
}
}
class Foo{
public synchronized static void dosome(){
try {
Thread t=Thread.currentThread();
System.out.println(t.getName()+":准备开始!");
Thread.sleep(5000);
System.out.println(t.getName()+":结束完毕!");
} catch (Exception e) {
e.printStackTrace();
}
}
}

***************************************************************************************************

public class demo4 {
public static void main(String[] args) {
final Boo boo=new Boo();
Thread t1=new Thread(){
public void run(){
boo.methodA();
}
};
Thread t2=new Thread(){
public void run(){
boo.methodB();
}
};
t1.start();
t2.start();
}
}
class Boo{
public synchronized void methodA(){
try {
Thread t=Thread.currentThread();
System.out.println(t.getName()+":A开始了");
Thread.sleep(5000);
System.out.println(t.getName()+":A结束了");
} catch (Exception e) {

}
}
public synchronized void methodB(){
try {
Thread t=Thread.currentThread();
System.out.println(t.getName()+":B开始了");
Thread.sleep(5000);
System.out.println(t.getName()+":B结束了");
} catch (Exception e) {

}
}
}

*************************************************************************************************

转换为线程安全的

public class demo5 {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
System.out.println(list);
//将给定集合转化为线程安全的集合
list=Collections.synchronizedList(list);
System.out.println(list);

Set<String> set=new HashSet<String>(list);
System.out.println(set);
//将set集合转化为线程安全的
set=Collections.synchronizedSet(set);
System.out.println(set);

Map<String,Integer> map=new HashMap<String,Integer>();
map.put("语文",98);
map.put("数学", 97);
map.put("英语",95);
System.out.println(map);
//将map转换为线程安全的
map=Collections.synchronizedMap(map);
System.out.println(map);
}
}

***********************************************************************************************

线程池的方法

public class demo6 {
public static void main(String[] args) {
ExecutorService threadPool=Executors.newFixedThreadPool(2);

for(int i=0;i<5;i++){
Runnable runn=new Runnable(){
public void run(){
Thread t=Thread.currentThread();
try {
System.out.println(t+":正在运行线程!");
Thread.sleep(5000);
System.out.println(t+":运行完毕!");
} catch (InterruptedException e) {
System.out.println("线程被中断了");
}
}
};
threadPool.execute(runn);
System.out.println("指派了一个任务交给线程池");
}
threadPool.shutdownNow();
System.out.println("停止线程池了");
}
}


原创粉丝点击