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
- Java多线程系列-目录
- Java多线程系列目录
- Java多线程系列目录
- Java多线程系列文档目录
- Java多线程系列目录(共43篇)
- Java多线程系列目录(共43篇)
- Java多线程系列目录(共43篇)
- Java多线程系列目录(共43篇)
- Java多线程系列目录(共43篇)——转载
- Java多线程目录整理
- java--多线程--目录
- Java系列教程目录
- java多线程系列
- java多线程系列:锁
- java多线程系列02
- java多线程系列03
- Java多线程系列-BlockingQueue
- Java多线程系列-Executors
- Android Studio 2.3 在小米手机中 调试安装Apk失败
- HTML5 3D旋转图片相册
- 将第三方组件react-native-swiper应用在欢迎界面中
- 最近发现了好多好资源,赶紧收藏一下!【粒子特效】
- Oracle导dmp出现文件ORA-12154: TNS: 无法解析指定的连接标识符解决方案
- Java多线程系列目录
- oracle 转mysql的newID()
- xhost 命令用途
- JavaScript—一元操作符:delete、typeof、void
- 我的Java之旅 第五课 JAVA 语言语法 集合
- Android手势ImageView三部曲(三)
- A股-入门-历史上的两会股票行情对比
- Activity搭载多个fragment中webview返回事件的处理
- jsp中获取当前项目名称,即当前URL