一 线程分析
1.在主线程中调用的线程中的函数,是在主线程中吗?确认是。
2.对象被其他线程锁住,主线程能进行设置吗?能
3.对象设置的函数被锁住,其他线程能对其中的变量进行设置吗?确认,不能。(这里只是实验结果,对象都没锁住,这里怎么可能锁住呢,难道被锁住的全部数据都不允许其他线程写了吗?待确认)
4.变量被锁期间,其他线程可以读吗?可以。
二 代码实验
2.1.试验1
线程中的函数,和在主线程中直接调用,是处在同一线程吗?
确认:不是
2.1.1 代码
package testJava2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class XianChengShuo {
public static void main(String[] args) {
System.out.println("线程实验?");
System.out.println("锁对象和锁函数的差别?");
XianChengShuo ccs = new XianChengShuo();
ccs.main();
}
void main() {
MyThread myThread = new MyThread();
// 这两个函数在同一进程中吗
new Thread(myThread).start();
for (int i = 0; i < 5; i++) {
myThread.play();
}
}
class MyThread implements Runnable {
public int numb = 0;
public void run() {
Date date = new Date();
Calendar beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.MINUTE, 5);
Date endDate = beforeTime.getTime();
while (true) {
add();
Date courentDae = new Date();
// 5分钟后自动停止
if(courentDae.after(endDate)) {
System.out.println("线程退出");
break;
}
}
}
public void add() {
String funName = "add";
playTime(true, funName);
numb++;
sleep(100l);
playTime(false, funName);
}
public void play() {
String funName = "play";
playTime(true, funName);
System.out.println(numb);
sleep(50l);
playTime(false, funName);
}
private void sleep(Long shijian) {
try {
Thread.sleep(shijian);
} catch (Exception e) {
}
}
private void playTime(boolean isStart, String funName) {
Thread t = Thread.currentThread();
String name = t.getName();
String isEnd = "end:";
if (isStart) {
isEnd = "start:";
}
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
String sj = sdf.format(d);
System.out.println(
"线程名称" + name + " 函数名" + funName + " " + isEnd + sj);
}
}
}
2.1.2 运行结果
线程实验?
锁对象和锁函数的差别?
线程名称Thread-0 函数名add start:2020-09-24 09:52:43.043
线程名称main 函数名play start:2020-09-24 09:52:43.043
1
线程名称main 函数名play end:2020-09-24 09:52:43.043
线程名称main 函数名play start:2020-09-24 09:52:43.043
1
线程名称Thread-0 函数名add end:2020-09-24 09:52:43.043
线程名称main 函数名play end:2020-09-24 09:52:43.043
线程名称Thread-0 函数名add start:2020-09-24 09:52:43.043
线程名称main 函数名play start:2020-09-24 09:52:43.043
2
线程名称main 函数名play end:2020-09-24 09:52:43.043
线程名称main 函数名play start:2020-09-24 09:52:43.043
2
线程名称Thread-0 函数名add end:2020-09-24 09:52:43.043
线程名称main 函数名play end:2020-09-24 09:52:43.043
线程名称Thread-0 函数名add start:2020-09-24 09:52:43.043
线程名称main 函数名play start:2020-09-24 09:52:43.043
3
线程名称main 函数名play end:2020-09-24 09:52:43.043
线程名称Thread-0 函数名add end:2020-09-24 09:52:43.043
线程名称Thread-0 函数名add start:2020-09-24 09:52:43.043
线程名称Thread-0 函数名add end:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add start:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add end:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add start:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add end:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add start:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add end:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add start:2020-09-24 09:52:44.044
线程名称Thread-0 函数名add end:2020-09-24 09:52:44.044
2.1. 3 代码分析

2.2 实验2
锁函数:锁函数后,线程set的对象仍然可以被get
2.2.1 代码
package testJava2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class XianChengShuo {
public static void main(String[] args) {
System.out.println("线程实验?");
System.out.println("锁对象和锁函数的差别?");
XianChengShuo ccs = new XianChengShuo();
ccs.main();
}
void main() {
MyThread myThread = new MyThread();
// 这两个函数在同一进程中吗
new Thread(myThread).start();
for (int i = 0; i < 5; i++) {
myThread.play();
}
}
class MyThread implements Runnable {
public int numb = 0;
public void run() {
Date date = new Date();
Calendar beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.MINUTE, 1);
Date endDate = beforeTime.getTime();
while (true) {
add();
Date courentDae = new Date();
// 5分钟后自动停止
if(courentDae.after(endDate)) {
System.out.println("线程退出");
break;
}
}
}
//锁函数
public synchronized void add() {
String funName = "add";
playTime(true, funName);
numb++;
sleep(100l);
playTime(false, funName);
}
public void play() {
String funName = "play";
playTime(true, funName);
System.out.println(numb);
sleep(50l);
playTime(false, funName);
}
private void sleep(Long shijian) {
try {
Thread.sleep(shijian);
} catch (Exception e) {
}
}
private void playTime(boolean isStart, String funName) {
Thread t = Thread.currentThread();
String name = t.getName();
String isEnd = "end:";
if (isStart) {
isEnd = "start:";
}
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
String sj = sdf.format(d);
System.out.println(
"线程名称" + name + " 函数名" + funName + " " + isEnd + sj);
}
}
}
2.2 .2 运行结果
线程实验?
锁对象和锁函数的差别?
线程名称Thread-0 函数名add start:2020-09-24 09:58:07.007
线程名称main 函数名play start:2020-09-24 09:58:07.007
1
线程名称main 函数名play end:2020-09-24 09:58:07.007
线程名称main 函数名play start:2020-09-24 09:58:07.007
1
线程名称main 函数名play end:2020-09-24 09:58:07.007
线程名称Thread-0 函数名add end:2020-09-24 09:58:07.007
线程名称main 函数名play start:2020-09-24 09:58:07.007
1
线程名称Thread-0 函数名add start:2020-09-24 09:58:07.007
线程名称main 函数名play end:2020-09-24 09:58:07.007
线程名称main 函数名play start:2020-09-24 09:58:07.007
2
线程名称Thread-0 函数名add end:2020-09-24 09:58:07.007
线程名称main 函数名play end:2020-09-24 09:58:07.007
线程名称main 函数名play start:2020-09-24 09:58:07.007
2
线程名称Thread-0 函数名add start:2020-09-24 09:58:07.007
线程名称main 函数名play end:2020-09-24 09:58:07.007
线程名称Thread-0 函数名add end:2020-09-24 09:58:08.008
线程名称Thread-0 函数名add start:2020-09-24 09:58:08.008
线程名称Thread-0 函数名add end:2020-09-24 09:58:08.008
2.2.3 代码分析

2.3 实验3
目的:锁对象是否影响其他线程读,确认没有影响
2.3.1 代码
package testJava2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class XianChengShuo {
public static void main(String[] args) {
System.out.println("线程实验?");
System.out.println("锁对象和锁函数的差别?");
XianChengShuo ccs = new XianChengShuo();
ccs.main();
}
void main() {
MyThread myThread = new MyThread();
// 这两个函数在同一进程中吗
new Thread(myThread).start();
for (int i = 0; i < 5; i++) {
myThread.play();
//myThread.set(i);
}
}
class MyThread implements Runnable {
public Integer numb = 0;
public void run() {
Date date = new Date();
Calendar beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.MINUTE, 1);
Date endDate = beforeTime.getTime();
while (true) {
add();
Date courentDae = new Date();
// 5分钟后自动停止
if(courentDae.after(endDate)) {
System.out.println("线程退出");
break;
}
}
}
//锁对象
public void add() {
synchronized(numb) {
String funName = "add";
playTime(true, funName);
numb++;
sleep(1000l);
playTime(false, funName);
}
}
public void play() {
String funName = "play";
playTime(true, funName);
System.out.println(numb);
sleep(500l);
playTime(false, funName);
}
/*
* public void set(int value) { String funName = "set"; playTime(true,
* funName); numb = value;
* System.out.println("numb:"+numb+" value"+value); sleep(50l);
* playTime(false, funName); }
*/
private void sleep(Long shijian) {
try {
Thread.sleep(shijian);
} catch (Exception e) {
}
}
private void playTime(boolean isStart, String funName) {
Thread t = Thread.currentThread();
String name = t.getName();
String isEnd = "end:";
if (isStart) {
isEnd = "start:";
}
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
String sj = sdf.format(d);
System.out.println(
"线程名称" + name + " 函数名" + funName + " " + isEnd + sj);
}
}
}
2.3.2 运行结果
线程实验?
锁对象和锁函数的差别?
线程名称main 函数名play start:2020-09-24 10:24:13.013
线程名称Thread-0 函数名add start:2020-09-24 10:24:13.013
0
线程名称main 函数名play end:2020-09-24 10:24:13.013
线程名称main 函数名play start:2020-09-24 10:24:13.013
1
线程名称Thread-0 函数名add end:2020-09-24 10:24:14.014
线程名称Thread-0 函数名add start:2020-09-24 10:24:14.014
线程名称main 函数名play end:2020-09-24 10:24:14.014
线程名称main 函数名play start:2020-09-24 10:24:14.014
2
线程名称main 函数名play end:2020-09-24 10:24:14.014
线程名称main 函数名play start:2020-09-24 10:24:14.014
2
线程名称main 函数名play end:2020-09-24 10:24:15.015
线程名称Thread-0 函数名add end:2020-09-24 10:24:15.015
线程名称main 函数名play start:2020-09-24 10:24:15.015
线程名称Thread-0 函数名add start:2020-09-24 10:24:15.015
2
线程名称main 函数名play end:2020-09-24 10:24:15.015
线程名称Thread-0 函数名add end:2020-09-24 10:24:16.016
2.3.3 代码分析

2.4 实验4
目的:锁对象是否影响其他线程写
2.4.1 代码
package testJava2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class XianChengShuo {
public static void main(String[] args) {
System.out.println("线程实验?");
System.out.println("锁对象和锁函数的差别?");
XianChengShuo ccs = new XianChengShuo();
ccs.main();
}
void main() {
MyThread myThread = new MyThread();
// 这两个函数在同一进程中吗
new Thread(myThread).start();
for (int i = 0; i < 5; i++) {
myThread.play();
myThread.set(i);
}
}
class MyThread implements Runnable {
public Integer numb = 0;
public void run() {
Date date = new Date();
Calendar beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.MINUTE, 1);
Date endDate = beforeTime.getTime();
while (true) {
add();
Date courentDae = new Date();
// 5分钟后自动停止
if(courentDae.after(endDate)) {
System.out.println("线程退出");
break;
}
}
}
//锁对象
public void add() {
synchronized(numb) {
String funName = "add";
playTime(true, funName);
numb++;
sleep(1000l);
playTime(false, funName);
}
}
public void play() {
String funName = "play";
playTime(true, funName);
System.out.println(numb);
sleep(500l);
playTime(false, funName);
}
public void set(int value) {
String funName = "set";
playTime(true, funName);
numb = value;
System.out.println("numb:"+numb+" value"+value);
sleep(50l);
playTime(false, funName);
}
private void sleep(Long shijian) {
try {
Thread.sleep(shijian);
} catch (Exception e) {
}
}
private void playTime(boolean isStart, String funName) {
Thread t = Thread.currentThread();
String name = t.getName();
String isEnd = "end:";
if (isStart) {
isEnd = "start:";
}
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
String sj = sdf.format(d);
System.out.println(
"线程名称" + name + " 函数名" + funName + " " + isEnd + sj);
}
}
}
2.4.2 运行结果
线程实验?
锁对象和锁函数的差别?
线程名称Thread-0 函数名add start:2020-09-24 10:16:08.008
线程名称main 函数名play start:2020-09-24 10:16:08.008
1
线程名称main 函数名play end:2020-09-24 10:16:09.009
线程名称main 函数名set start:2020-09-24 10:16:09.009
numb:0 value0
线程名称main 函数名set end:2020-09-24 10:16:09.009
线程名称main 函数名play start:2020-09-24 10:16:09.009
0
线程名称Thread-0 函数名add end:2020-09-24 10:16:09.009
线程名称Thread-0 函数名add start:2020-09-24 10:16:09.009
线程名称main 函数名play end:2020-09-24 10:16:09.009
线程名称main 函数名set start:2020-09-24 10:16:09.009
numb:1 value1
线程名称main 函数名set end:2020-09-24 10:16:09.009
线程名称main 函数名play start:2020-09-24 10:16:09.009
1
线程名称main 函数名play end:2020-09-24 10:16:10.010
线程名称main 函数名set start:2020-09-24 10:16:10.010
numb:2 value2
线程名称main 函数名set end:2020-09-24 10:16:10.010
线程名称main 函数名play start:2020-09-24 10:16:10.010
2
线程名称Thread-0 函数名add end:2020-09-24 10:16:10.010
线程名称Thread-0 函数名add start:2020-09-24 10:16:10.010
线程名称main 函数名play end:2020-09-24 10:16:11.011
线程名称main 函数名set start:2020-09-24 10:16:11.011
numb:3 value3
线程名称main 函数名set end:2020-09-24 10:16:11.011
线程名称main 函数名play start:2020-09-24 10:16:11.011
3
线程名称main 函数名play end:2020-09-24 10:16:11.011
线程名称main 函数名set start:2020-09-24 10:16:11.011
numb:4 value4
线程名称main 函数名set end:2020-09-24 10:16:11.011
线程名称Thread-0 函数名add end:2020-09-24 10:16:11.011
2.4.3 代码分析

2.5
2.5.1 实验5-1
2.5.1.1 代码
package testJava2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class XianChengShuo {
public static void main(String[] args) {
System.out.println("线程实验?");
System.out.println("锁对象和锁函数的差别?");
XianChengShuo ccs = new XianChengShuo();
ccs.main();
}
void main() {
MyThread myThread = new MyThread();
// 这两个函数在同一进程中吗
new Thread(myThread).start();
for (int i = 0; i < 5; i++) {
myThread.play();
myThread.set(i);
}
}
class MyThread implements Runnable {
public Integer numb = 0;
public void run() {
Date date = new Date();
Calendar beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.MINUTE, 1);
Date endDate = beforeTime.getTime();
while (true) {
add();
Date courentDae = new Date();
// 5分钟后自动停止
if (courentDae.after(endDate)) {
System.out.println("线程退出");
break;
}
}
}
// 锁对象
public void add() {
synchronized (numb) {
String funName = "add"+numb;
playTime(true, funName);
System.out.println("add:"+(++numb));
sleep(1000l);
numb++;
System.out.println("add:"+(++numb));
playTime(false, funName);
}
}
public void play() {
String funName = "play";
playTime(true, funName);
System.out.println(numb);
sleep(500l);
playTime(false, funName);
}
public void set(int value) {
String funName = "set";
playTime(true, funName);
numb = value;
System.out.println("numb:" + numb + " value" + value);
sleep(1000l);
playTime(false, funName);
}
private void sleep(Long shijian) {
try {
Thread.sleep(shijian);
} catch (Exception e) {
}
}
private void playTime(boolean isStart, String funName) {
Thread t = Thread.currentThread();
String name = t.getName();
String isEnd = "end:";
if (isStart) {
isEnd = "start:";
}
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
String sj = sdf.format(d);
System.out.println(
"线程名称" + name + " 函数名" + funName + " " + isEnd + sj);
}
}
}
2.5.1.2 结果
线程实验?
锁对象和锁函数的差别?
线程名称Thread-0 函数名add0 start:2020-09-24 10:34:06.006
线程名称main 函数名play start:2020-09-24 10:34:06.006
add:1
1
线程名称main 函数名play end:2020-09-24 10:34:06.006
线程名称main 函数名set start:2020-09-24 10:34:06.006
numb:0 value0
add:2
线程名称Thread-0 函数名add0 end:2020-09-24 10:34:07.007
线程名称Thread-0 函数名add2 start:2020-09-24 10:34:07.007
add:3
线程名称main 函数名set end:2020-09-24 10:34:07.007
线程名称main 函数名play start:2020-09-24 10:34:07.007
3
add:5
线程名称main 函数名play end:2020-09-24 10:34:08.008
线程名称Thread-0 函数名add2 end:2020-09-24 10:34:08.008
线程名称main 函数名set start:2020-09-24 10:34:08.008
numb:1 value1
线程名称Thread-0 函数名add5 start:2020-09-24 10:34:08.008
add:2
add:4
线程名称Thread-0 函数名add5 end:2020-09-24 10:34:09.009
线程名称main 函数名set end:2020-09-24 10:34:09.009
线程名称Thread-0 函数名add4 start:2020-09-24 10:34:09.009
add:5
线程名称main 函数名play start:2020-09-24 10:34:09.009
5
线程名称main 函数名play end:2020-09-24 10:34:09.009
线程名称main 函数名set start:2020-09-24 10:34:09.009
numb:2 value2
2.5.1.3 代码分析

2.5.2 实验5-2
2.5.2.1 代码
package testJava2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class XianChengShuo {
public static void main(String[] args) {
System.out.println("线程实验?");
System.out.println("锁对象和锁函数的差别?");
XianChengShuo ccs = new XianChengShuo();
ccs.main();
}
void main() {
MyThread myThread = new MyThread();
// 这两个函数在同一进程中吗
new Thread(myThread).start();
for (int i = 0; i < 5; i++) {
myThread.play();
myThread.set(i);
}
}
class MyThread implements Runnable {
public Integer numb = 0;
public void run() {
Date date = new Date();
Calendar beforeTime = Calendar.getInstance();
beforeTime.add(Calendar.MINUTE, 1);
Date endDate = beforeTime.getTime();
while (true) {
add();
Date courentDae = new Date();
// 5分钟后自动停止
if (courentDae.after(endDate)) {
System.out.println("线程退出");
break;
}
}
}
// 锁对象
public synchronized void add() {
String funName = "add"+numb;
playTime(true, funName);
System.out.println("add:"+(++numb));
sleep(1000l);
numb++;
System.out.println("add:"+(++numb));
playTime(false, funName);
}
public void play() {
String funName = "play";
playTime(true, funName);
System.out.println(numb);
sleep(500l);
playTime(false, funName);
}
public synchronized void set(int value) {
String funName = "set";
playTime(true, funName);
numb = value;
System.out.println("numb:" + numb + " value" + value);
sleep(1000l);
playTime(false, funName);
}
private void sleep(Long shijian) {
try {
Thread.sleep(shijian);
} catch (Exception e) {
}
}
private void playTime(boolean isStart, String funName) {
Thread t = Thread.currentThread();
String name = t.getName();
String isEnd = "end:";
if (isStart) {
isEnd = "start:";
}
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss.sss");
String sj = sdf.format(d);
System.out.println(
"线程名称" + name + " 函数名" + funName + " " + isEnd + sj);
}
}
}
2.5.2.2
线程实验?
锁对象和锁函数的差别?
线程名称main 函数名play start:2020-09-24 10:45:48.048
线程名称Thread-0 函数名add0 start:2020-09-24 10:45:48.048
0
add:1
线程名称main 函数名play end:2020-09-24 10:45:49.049
add:3
线程名称Thread-0 函数名add0 end:2020-09-24 10:45:49.049
线程名称main 函数名set start:2020-09-24 10:45:49.049
numb:0 value0
线程名称main 函数名set end:2020-09-24 10:45:50.050
线程名称Thread-0 函数名add0 start:2020-09-24 10:45:50.050
add:1
线程名称main 函数名play start:2020-09-24 10:45:50.050
1
线程名称main 函数名play end:2020-09-24 10:45:51.051
add:3
线程名称Thread-0 函数名add0 end:2020-09-24 10:45:51.051
线程名称Thread-0 函数名add3 start:2020-09-24 10:45:51.051
add:4
add:6
线程名称Thread-0 函数名add3 end:2020-09-24 10:45:52.052
线程名称Thread-0 函数名add6 start:2020-09-24 10:45:52.052
add:7
add:9
线程名称Thread-0 函数名add6 end:2020-09-24 10:45:53.053
线程名称Thread-0 函数名add9 start:2020-09-24 10:45:53.053
add:10
add:12
线程名称Thread-0 函数名add9 end:2020-09-24 10:45:54.054
线程名称Thread-0 函数名add12 start:2020-09-24 10:45:54.054
add:13
add:15
线程名称Thread-0 函数名add12 end:2020-09-24 10:45:55.055
线程名称Thread-0 函数名add15 start:2020-09-24 10:45:55.055
add:16
add:18
线程名称Thread-0 函数名add15 end:2020-09-24 10:45:56.056
线程名称main 函数名set start:2020-09-24 10:45:56.056
numb:1 value1
线程名称main 函数名set end:2020-09-24 10:45:57.057
线程名称main 函数名play start:2020-09-24 10:45:57.057
1
线程名称Thread-0 函数名add1 start:2020-09-24 10:45:57.057
add:2
线程名称main 函数名play end:2020-09-24 10:45:58.058
add:4
线程名称Thread-0 函数名add1 end:2020-09-24 10:45:58.058
线程名称Thread-0 函数名add4 start:2020-09-24 10:45:58.058
add:5
add:7
线程名称Thread-0 函数名add4 end:2020-09-24 10:45:59.059
线程名称Thread-0 函数名add7 start:2020-09-24 10:45:59.059
add:8
add:10
线程名称Thread-0 函数名add7 end:2020-09-24 10:46:00.000
线程名称main 函数名set start:2020-09-24 10:46:00.000
numb:2 value2
线程名称main 函数名set end:2020-09-24 10:46:01.001
线程名称Thread-0 函数名add2 start:2020-09-24 10:46:01.001
2.5.2.3 代码分析

本文通过一系列实验,探讨了Java中线程同步的不同方法,包括锁对象和锁函数,以及它们对读写操作的影响。实验表明,锁函数可以防止同一函数内的并发执行,但不影响其他线程读取;而锁对象则限制了对象级别的访问,确保了写操作的互斥,同时也允许其他线程进行读取。
1094

被折叠的 条评论
为什么被折叠?



