「java线程sync」java线程池参数
今天给各位分享java线程sync的知识,其中也会对java线程池参数进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
浅谈Java多线程的同步问题
多线程的同步依靠的是对象锁机制 synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问
下面以一个简单的实例来进行对比分析 实例要完成的工作非常简单 就是创建 个线程 每个线程都打印从 到 这 个数字 我们希望线程之间不会出现交叉乱序打印 而是顺序地打印
先来看第一段代码 这里我们在run()方法中加入了synchronized关键字 希望能对run方法进行互斥访问 但结果并不如我们希望那样 这是因为这里synchronized锁住的是this对象 即当前运行线程对象本身 代码中创建了 个线程 而每个线程都持有this对象的对象锁 这不能实现线程的同步
代码 package vista; class MyThread implements java lang Runnable { private int threadId;
public MyThread(int id) { this threadId = id; }
@Override public synchronized void run() { for (int i = ; i ; ++i) { System out println( Thread ID: + this threadId + : + i); } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = ; i ; ++i) { new Thread(new MyThread(i)) start(); Thread sleep( ); } } }
从上述代码段可以得知 要想实现线程的同步 则这些线程必须去竞争一个唯一的共享的对象锁
基于这种思想 我们将第一段代码修改如下所示 在创建启动线程之前 先创建一个线程之间竞争使用的Object对象 然后将这个Object对象的引用传递给每一个线程对象的lock成员变量 这样一来 每个线程的lock成员都指向同一个Object对象 我们在run方法中 对lock对象使用synchronzied块进行局部封锁 这样就可以让线程去竞争这个唯一的共享的对象锁 从而实现同步
代码 package vista;
class MyThread implements java lang Runnable { private int threadId; private Object lock;
public MyThread(int id Object obj) { this threadId = id; this lock = obj; }
@Override public void run() { synchronized (lock) { for (int i = ; i ; ++i) { System out println( Thread ID: + this threadId + : + i); } } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Object obj = new Object(); for (int i = ; i ; ++i) { new Thread(new MyThread(i obj)) start(); Thread sleep( ); } } }
从第二段代码可知 同步的关键是多个线程对象竞争同一个共享资源即可 上面的代码中是通过外部创建共享资源 然后传递到线程中来实现 我们也可以利用类成员变量被所有类的实例所共享这一特性 因此可以将lock用静态成员对象来实现 代码如下所示
代码 package vista;
class MyThread implements java lang Runnable { private int threadId; private static Object lock = new Object();
public MyThread(int id) { this threadId = id; }
@Override public void run() { synchronized (lock) { for (int i = ; i ; ++i) { System out println( Thread ID: + this threadId + : + i); } } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = ; i ; ++i) { new Thread(new MyThread(i)) start(); Thread sleep( ); } } }
再来看第一段代码 实例方法中加入sychronized关键字封锁的是this对象本身 而在静态方法中加入sychronized关键字封锁的就是类本身 静态方法是所有类实例对象所共享的 因此线程对象在访问此静态方法时是互斥访问的 从而可以实现线程的同步 代码如下所示
代码 package vista;
class MyThread implements java lang Runnable { private int threadId;
public MyThread(int id) { this threadId = id; }
@Override public void run() { taskHandler(this threadId); }
private static synchronized void taskHandler(int threadId) { for (int i = ; i ; ++i) { System out println( Thread ID: + threadId + : + i); } } }
lishixinzhi/Article/program/Java/gj/201311/27441
Java多线程初学者指南(12):使用Synchronized块同步变量
我们可以通过synchronized块来同步特定的静态或非静态方法 要想实现这种需求必须为这些特性的方法定义一个类变量 然后将这些方法的代码用synchronized块括起来 并将这个类变量作为参数传入synchronized块 下面的代码演示了如何同步特定的类方法
package mythread; public class SyncThread extends Thread { private static String sync = ; private String methodType = ; private static void method(String s) { synchronized (sync) { sync = s; System out println(s); while (true); } } public void method () { method( method ); } public static void staticMethod () { method( staticMethod ); } public void run() { if (methodType equals( static )) staticMethod (); else if (methodType equals( nonstatic )) method (); } public SyncThread(String methodType) { thodType = methodType; } public static void main(String[] args) throws Exception { SyncThread sample = new SyncThread( nonstatic ); SyncThread sample = new SyncThread( static ); sample start(); sample start(); } }
运行结果如下
method staticMethod
看到上面的运行结果很多读者可能感到惊奇 在上面的代码中method 和staticMethod 方法使用了静态字符串变量sync进行同步 这两个方法只能有一个同时执行 而这两个方法都会执行 行的无限循环语句 因此 输出结果只能是method 和staticMethod 其中之一 但这个程序将这两个字符串都输出了
出现这种结果的愿意很简单 我们看一下 行就知道了 原来在这一行将sync的值改变了 在这里要说一下Java中的String类型 String类型和Java中其他的复杂类型不同 在使用String型变量时 只要给这个变量赋一次值 Java就会创建个新的String类型的实例 如下面的代码所示
String s = hello ;System out println(s hashCode());s = world ;System out println(s hashCode());
在上面的代码中 第一个s和再次赋值后的s的hashCode的值是不一样的 由于创建String类的实例并不需要使用new 因此 在同步String类型的变量时要注意不要给这个变量赋值 否则会使变量无法同步
由于在 行已经为sync创建了一个新的实例 假设method 先执行 当method 方法执行了 行的代码后 sync的值就已经不是最初那个值了 而method 方法锁定的仍然是sync变量最初的那个值 而在这时 staticMethod 正好执行到synchronized(sync) 在staticMethod 方法中要锁定的这个sync和method 方法锁定的sync已经不是一个了 因此 这两个方法的同步性已经被破坏了
解决以上问题的方法当然是将 行去掉 在本例中加上这行 只是为了说明使用类变量来同步方法时如果在synchronized块中将同步变量的值改变 就会破坏方法之间的同步 为了彻底避免这种情况发生 在定义同步变量时可以使用final关键字 如将上面的程序中的 行可改成如下形式
private final static String sync = ;
使用final关键字后 sync只能在定义时为其赋值 并且以后不能再修改 如果在程序的其他地方给sync赋了值 程序就无法编译通过 在Eclipse等开发工具中 会直接在错误的地方给出提示
我们可以从两个角度来理解synchronized块 如果从类方法的角度来理解 可以通过类变量来同步相应的方法 如果从类变量的角度来理解 可以使用synchronized块来保证某个类变量同时只能被一个方法访问 不管从哪个角度来理解 它们的实质都是一样的 就是利用类变量来获得同步锁 通过同步锁的互斥性来实现同步
lishixinzhi/Article/program/Java/gj/201311/27400
Java类的实例化顺序是什么样的?Java线程同步的方式有哪些?
引言:java是在1990年初 ,被詹姆斯•高斯林等人开发的一门面向对象的编程语言。起初,java被称为0ak,来经过发展0ak改名为java,与1995年的五月份正式向大家发布。
一、java类的实例化顺序
java的实例化顺序在继承没有的情况
单独一个类的场景下,初始化顺序为依次为静态数据,继承的基类的构造函数,成员变量,被调用的构造函数。
其中静态数据只会初始化一次。(静态数据包括静态代码块和静态变量,每个类的静态数据只会初始化一次)
在继承的情况下
添加两个基类,让继承父亲,父亲继承祖父。
继承的情况就比较复杂了。由继承了基类,还将往上回溯,递归地调用基类的无参构造方法。
在我们的例子中,在初始化静态数据后,会先往上追溯,调用父的默认构造方法,此时再往上追溯到爷爷的默认构造方法。
二、信息技术的不断发展
java也体现了现代社会下信息技术的不断发展,科技水平的不断进步,人们的工作也越来越便利,日常生活也越来越方便,越来越多的工具被人们所开发应用 。科技的发展也要求我们掌握更多的知识,在探索的过程中,我们需要明白更方便的方法使用更便捷的方法来取得成就,我的方法会让过程事半功倍。科技的发展也要求我们掌握越来越多的知识,我们可以通过学习来获得更多的知识,来帮助我们在以后的工作生活,多些技能总是有好处的 。
无论是java还是什么别的东西他都体现了现代社会与信息技术的不断发展,人们在进行进行技术开发时也有了越来越多的方法。程序类的工作也有了更为快捷的方法,这为信息技术的发展也提供了更好的发展方法
关于java线程sync和java线程池参数的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-27,除非注明,否则均为
原创文章,转载请注明出处。