Java多线程系列目录

来源:互联网 发布:飞驰网络加速器 编辑:程序博客网 时间:2024/06/12 01:26

-----------------------------------------------------------

多线程系列目录

-----------------------------------------------------------------------

写一个定时器

import java.util.Timer;import java.util.TimerTask;public class TraditionalTimerTest {public static void main(String[] args) {new Timer().schedule(new TimerTask(){@Overridepublic void run() {System.out.println("booming!");}}, 2000, 2000);}}

2秒后开始炸,然后每隔2秒炸一次。

------------------------------------------------------------------------------------------------

public class TraditionalThreadSynchronized {public static void main(String[] args) {new TraditionalThreadSynchronized().init();}private void init(){final Outputer outputer=new Outputer();new Thread(new Runnable(){@Overridepublic void run() {while(true){try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}outputer.output("reed1991");}}}).start();new Thread(new Runnable(){@Overridepublic void run() {while(true){try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}outputer.output("fanqunsong");}}}).start();}static class Outputer{public void output(String name){int len=name.length();synchronized (name){for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}}}

互斥必须使用的是同一个对象,两个对象的name不一样,所以对name加锁无效,还是会出现线程安全问题,如下图

------------------------------------------------------------------------------------------------------------------


--------------------------------------------------------------------------

修改如下

static class Outputer{String xxx="";public void output(String name){int len=name.length();synchronized (xxx){for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}

就改成了对Outputer加锁,能保证线程安全。

或者这么改,直接对调用的对象加锁

static class Outputer{public void output(String name){int len=name.length();synchronized (this){for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}

或者直接在方法前面加锁,如下

public synchronized void output2(String name){int len = name.length();for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}

-------------------------------------------------------------------------------------------------------

public class TraditionalThreadSynchronized {public static void main(String[] args) {new TraditionalThreadSynchronized().init();}private void init(){final Outputer outputer=new Outputer();new Thread(new Runnable(){@Overridepublic void run() {while(true){try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}outputer.output("reed1991");}}}).start();new Thread(new Runnable(){@Overridepublic void run() {while(true){try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}outputer.output2("fanqunsong");}}}).start();}static class Outputer{public void output(String name){int len=name.length();synchronized (this){for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}public static synchronized void output2(String name){int len = name.length();for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}}
会出现线程安全问题

静态对象跟字节码类的对象关联,做如下修改

static class Outputer{public void output(String name){int len=name.length();synchronized (Outputer.class){for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}public static synchronized void output2(String name){int len = name.length();for(int i=0;i<len;i++){System.out.print(name.charAt(i));}System.out.println();}}}

即可保证线程安全

---------------------------------------------------------------------------------------------------------------------------

要用到共同数据(包括同步锁)或共同算法的若干个方法应归在同一个类身上。

怎么实现子循环循环10次,主循环循环5次,交替循环50次。

public class TraditionalThreadCommunication {public static void main(String[] args) {final Business business=new Business();new Thread(new Runnable(){@Overridepublic void run() {for(int i=1;i<=50;i++)business.sub(i);}}).start();for(int i=1;i<=50;i++)business.main(i);}}class Business{private boolean bShouldSub=true;public synchronized void sub(int i) {while(!bShouldSub){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}for(int j=1;j<=10;j++)System.out.println("sub thread sequence of " + j + ",loop of " + i);bShouldSub=false;this.notify();}public synchronized void main(int i){while(bShouldSub){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}for(int j=1;j<=5;j++){System.out.println("main thread sequence of " + j + ",loop of " + i);}bShouldSub = true;this.notify();}}

---------------------------------------------------------------------------------------------------------------------------------------------------------

用如下代码来说明如何实现全局共享:

每个线程调用自己的set方法,就相当往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值。

import java.util.HashMap;import java.util.Map;import java.util.Random;public class ThreadScopeShareData {private static int data=0;private static Map<Thread,Integer>threadData=new HashMap<Thread,Integer>();public static void main(String[] args) {for(int i=0;i<2;i++){new Thread(new Runnable(){@Overridepublic void run() {int data=new Random().nextInt();threadData.put(Thread.currentThread(), data);new A().get();new B().get();}}).start();}}static class A{public void get(){int data = threadData.get(Thread.currentThread());System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data);}}static class B{public void get(){int data = threadData.get(Thread.currentThread());System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data);}}}

运行结果

A from Thread-0 get data :1417580547
B from Thread-0 get data :1417580547
A from Thread-1 get data :-2068586270
B from Thread-1 get data :-2068586270


用ThreadLocal改写

public class ThreadLocalTest {private static int data=0;private static  ThreadLocal<Integer>   x= new  ThreadLocal<Integer>();public static void main(String[] args) {for(int i=0;i<2;i++){new Thread(new Runnable(){@Overridepublic void run() {int data=new Random().nextInt();x.set(data);new A().get();new B().get();}}).start();}}static class A{public void get(){int data = x.get();System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data);}}static class B{public void get(){int data = x.get();System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data);}}}


输出

A from Thread-0 get data :-560167778
A from Thread-1 get data :1107166147
B from Thread-1 get data :1107166147
B from Thread-0 get data :-560167778

实现对ThreadLocal变量的封装,让外界不要直接操作ThreadLocal变量

import java.util.Random;public class ThreadLocalTest {private static  ThreadLocal<Integer>   x= new  ThreadLocal<Integer>();private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();public static void main(String[] args) {for(int i=0;i<2;i++){new Thread(new Runnable(){@Overridepublic void run() {int data=new Random().nextInt();System.out.println(Thread.currentThread().getName() + " has put data :" + data);x.set(data);MyThreadScopeData.getThreadInstance().setName("name" + data);MyThreadScopeData.getThreadInstance().setAge(data);new A().get();new B().get();}}).start();}}static class A{public void get(){int data = x.get();System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data);MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();System.out.println("A from " + Thread.currentThread().getName() + " getMyData: " + myData.getName() + "," +myData.getAge());}}static class B{public void get(){int data = x.get();System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data);MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();System.out.println("B from " + Thread.currentThread().getName() + " getMyData: " + myData.getName() + "," +myData.getAge());}}}class MyThreadScopeData{private MyThreadScopeData(){};public static MyThreadScopeData getThreadInstance(){MyThreadScopeData instance=map.get();if(instance==null){instance=new  MyThreadScopeData();map.set(instance);}return instance;}private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

输出为

Thread-1 has put data :2118585801
Thread-0 has put data :-1493221660
A from Thread-1 get data :2118585801
A from Thread-1 getMyData: name2118585801,2118585801
A from Thread-0 get data :-1493221660
A from Thread-0 getMyData: name-1493221660,-1493221660
B from Thread-1 get data :2118585801
B from Thread-0 get data :-1493221660
B from Thread-1 getMyData: name2118585801,2118585801

0 0