首页 > 编程语言 >java && C# 线程

java && C# 线程

时间:2022-10-20 11:33:21浏览次数:40  
标签:java C# lock void System int 线程 str new

 

1、多个线程用到同一个资源的话,必须lock

2、为了解决,在竞争的情况下,优先分配资源给A。就是A和B线程都同时在同一时刻需要资源x,然后的话也不清楚系统是具体怎样调度的。或者说怎样调度,都有可能出现上面的问题。解决方法是:在分配资源的时候再增加一个请求,用来排队。以前的请求是,如果这个时候申请然后这个时候也没人在用,就给它。现在的是如果B需要x,先要查看A是否需要。感觉有点像增加代码,然后使得线程判断次数增加,多次调度。所以感觉没有根本解决问题。

也不是说没解决,但是感觉解决了99.9%。hack,对于同一时刻到来的,还是随机化先进性读,或者先进性写了。T__T

怎么说呢,就是读者一来,先申请需要资源,而不是判定是否能拿资源,然后能拿就给它。我们需要的是先申请,然后就相当于锁定了资源x了,后来的写者再需要,需要检查申请队列中是否有读者,有就不行。

3、合法后立马addSignal,不然会出现多个写者同时操作的问题。

4、get, set方法是有用的,对于多线程,还可以维护资源不被多个线程修改,Lock

 

所以我的感觉是:如果是这样的:

写者先判定while (getNeedReader() > 0) { },判断失败的。

然后读者addReader(1); 

然后写者while (getSignal() != 0) { } 也是失败的。

这样的话,结果还是给了写者。

很多人告诉我直接设置线程优先级,但是这样是不对的。因为线程的优先级只是说分配的时间片比较多,不保证上面的情况不能发生。

java && C# 线程_java

java && C# 线程_加锁_02

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
public partial class Form1 : Form {
static int signal = 0;//0:empty 1:read 2:write
static int numberReader = 0, numberWriter = 0;
private static object obj = new object();
private static object si = new object();
private static object reader = new object();
const int dis = 1000;
static Stopwatch timer1;
static int needReader = 0;
class temp {
public string[] str;
int getSignal() {
lock (si) {
return signal;
}
}
int getNumber() {
if (0 == getSignal()) return 0;
else if (1 == getSignal()) return numberReader;
else return numberWriter;
}
void addSignal(int id) {
lock (si) {
if (id == 1) {
signal = 1;
numberReader++;
} else {
signal = 2;
numberWriter++;
}
}
}
void cutSignal(int id) {
lock (si) {
if (id == 1) {
numberReader--;
if (numberReader == 0) signal = 0;
} else {
numberWriter--;
if (numberWriter == 0) signal = 0;
}
}
}



void addStringRichText(String str) {
lock (obj) {
Form1.richTextBox1.Text += str;
Form1.richTextBox1.Text += '\n';
Form1.richTextBox1.Focus();
Form1.richTextBox1.Select(Form1.richTextBox1.Text.Length, 0);
Form1.richTextBox1.ScrollToCaret();

}
}

void show(String[] str, int id) {
Console.Write(id + "+++ ");
for (int i = 0; i < str.Length; ++i) {
Console.Write(str[i] + " ");
}
Console.WriteLine("\n");
}

void addReader(int op) {
lock (reader) {
needReader += op;
}
}

int getNeedReader() {
lock (reader) {
return needReader;
}
}

void semWait(int id) {
if (id == 1) {
addReader(1); // 首先需要申请需要资源,直接资源锁定
if (getSignal() != 2) {
addSignal(id);
return;
}
while (getSignal() == 2) { } // 合法后立马addSignal
addSignal(1);
} else {
while (getNeedReader() > 0) { }
while (getSignal() != 0) { } //这句后面肯定要是addSignal,立马的
addSignal(2);
}
}

void semSignal(int id) {
if (id == 1) {
cutSignal(1);
addReader(-1);
} else {
cutSignal(2);
}
}

public void Reader() {
addStringRichText("读者:" + str[0] + " 线程创建");
Thread.Sleep(int.Parse(str[2]) * 1000);
addStringRichText("读者:" + str[0] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 请求读操作");

/*进行读操作*/
semWait(1);
addStringRichText("读者:" + str[0] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 开始读操作");
Thread.Sleep(int.Parse(str[3]) * 1000);
addStringRichText("读者:" + str[0] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 结束读操作");
semSignal(1);
/*读操作进行完毕*/



}
private static object w = new object();
public void Writer() {
addStringRichText("写者:" + str[0] + " 线程创建");
Thread.Sleep(int.Parse(str[2]) * 1000);
addStringRichText("写者:" + str[0] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 请求写操作");

semWait(2);
/*进行读操作*/

addStringRichText("写者:" + str[0] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 开始写操作");
Thread.Sleep(int.Parse(str[3]) * 1000);
addStringRichText("写者:" + str[0] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 结束写操作");
semSignal(2);
/*读操作进行完毕*/

}

}
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
OpenFileDialog op = new OpenFileDialog();
op.ShowDialog();
op.Filter = "All files(*.*)|*.*";
StreamReader reader = null;

try {
string fileName = op.FileName;
if (fileName == "") {
return;
}
richTextBox1.Clear();
reader = new StreamReader(fileName, System.Text.Encoding.Default);
string str = reader.ReadLine();
List<Thread> list = new List<Thread>();
while (str != null) {
string[] res = str.Split(' ');
temp zhu = new temp();
zhu.str = res;
if (str.Contains("R") || str.Contains("r")) {
Thread rThread = new Thread(zhu.Reader);
//rThread.Priority = ThreadPriority.AboveNormal;
rThread.Priority = ThreadPriority.AboveNormal;
list.Add(rThread);

} else if (str.Contains("W") || str.Contains("w")) {
Thread wThread = new Thread(zhu.Writer);
//wThread.Priority = ThreadPriority.BelowNormal;
list.Add(wThread);
} else {
MessageBox.Show("输入数据有错误!!!【每行数据后面不能有空格】,【文件结束不能有空行】");
return;
}
//MessageBox.Show(str);
str = reader.ReadLine();
}
timer1 = new Stopwatch();//计时器类
timer1.Start();
foreach (Thread i in list) {
i.Start();
}
} catch (Exception error) {
MessageBox.Show("错误信息是:" + error.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);

} finally {
if (reader != null) {
reader.Close();
}
}
const string MutexName = "Multithreading";
var m = new Mutex(false, MutexName);


}
private void richTextBox1_TextChanged(object sender, EventArgs e) {
}
private void Form1_Load(object sender, EventArgs e) {
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; //允许其他线程修改
}
}
}

View Code

 

所以,我感觉线程不是用于这样的东西的,这样的话结果不确定(或者是我太渣渣了)

线程应该是用在那些,计算方面,new一个线程来辅助计算

 

这个数据,就会显示是写者优先了,尽管我设置了优先级是读者AboveNormal

对了看到java里写,Main线程的优先级是Noraml的。

java && C# 线程_java

java && C# 线程_加锁_02

2 W 1 5
2 W 1 5
2 W 1 5
2 W 1 5
2 W 1 5
2 W 1 5
2 W 1 5
1 R 1 5

View Code

 

 

java说,

synchronized可以修饰一个同步一个方法,public synchronized void fun();

同步:就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。

java高级篇P326

一个同步方法在执行之前需要加锁,锁是一种实现资源排他使用的机制。对于实例方法,要给调用该方法的对象加锁。对于静态方法,要给这个类加锁。

 但是我不需要对整个类加锁啊,我对静态方法加锁也可以得,???不懂

class myThread implements Runnable {
public String s;

public void run() {
System.out.println(s);
}

static synchronized void fun() {

}
}

 

java的内部类如果需要new一个实体出来,

用name s = new name(); 是不行的。会"is not an enclosing class"

需要Main s = new Main(); 一个实例

然后Main.name bb = s.new name();

 

有一个问题就是,用lock的话,怎么解决只有一个return的语句呢???

因为lock.lock()之后,还需要lock.unlock()

java && C# 线程_java

java && C# 线程_加锁_02

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
static bank bk = new bank();
public static void main(String[] args) {
ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(new cutMoney());
ex.execute(new addMoney());
ex.shutdown();
}
static class addMoney implements Runnable {
@Override
public void run() {
while (true) {
int val = (int)(Math.random() * 10) + 1;
bk.add(val);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class cutMoney implements Runnable {
@Override
public void run() {
while (true) {
int val = (int)(Math.random() * 10) + 1;
try {
while (!bk.cut(val)) {}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

static class bank {
private Lock lock = new ReentrantLock();
private Condition signal = lock.newCondition();
private int money = 0;
bank() {}
// synchronized int getMoney() { // 只能这样嘛?用lock感觉不行啊
// return money;
// }
int getMoney() { // 只能这样嘛?用lock感觉不行啊
lock.lock();
try {
return money;
} finally {
lock.unlock();
}
}
String getNowTime() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");//设置日期格式
return (df.format(new Date()));// new Date()为获取当前系统时间
}
boolean cut(int val) throws InterruptedException {
lock.lock();
try {
while (money < val) {
System.out.println(getNowTime() + " 不够 " + val + " " + " 现在有 " + money);
signal.await(); //等待,不需要一直判判判
}
money -= val;
System.out.println(getNowTime() + " 扣除" + val + "钱");
} catch (InterruptedException e) {

} finally {
lock.unlock();
}
return true;

}
void add(int val) {
lock.lock();
try {
money += val;
System.out.println(getNowTime() + " 转入" + val + "钱");
signal.signalAll(); // 唤醒
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}

减钱加钱

 

我的方法是:

1、用synchronized

2、try的finally语句是必须进行的

标签:java,C#,lock,void,System,int,线程,str,new
From: https://blog.51cto.com/u_15833059/5779595

相关文章

  • Docker能干嘛
    Docker能干嘛之前的虚拟机技术​虚拟机技术缺点:​资源占用十分多​冗余步骤多​启动很慢​容器化技术​比较Docker和虚拟机技术的不同:​传统虚拟机,虚拟出一些硬件,运行一个完......
  • 软件使用---Eclipse
    代码提示快捷操作。这个叫做,内容分析(contentassist)1、设置自动提示:2、设置快捷键: ......
  • leetcode 197. Rising Temperature sql_Date用法
    ​​https://leetcode.com/problems/rising-temperature/description/​​题目需要选出今天比昨天气温高的ID用join,默认是inner join需要左右两边同时有才行。然后就是用on......
  • 第三十四章 Centos7下Docker安装RabbitMQ
    一、拉取RabbitMQ镜像文件#官网:https://www.rabbitmq.com/networking.html[root@testtech2-180~]#dockerpullrabbitmq:management二、启动RabbitMQ[root@testte......
  • C# 后台获取天气情况
      转载:http://t.zoukankan.com/gaohongchen01-p-5535694.html 本文使用C#开发Winform应用程序,通过调用<WebXml/>(URL:http://www.webxml.com.cn)的WebService服务Wea......
  • 2022-10-20 微信浏览器css定位异常
    如题,一个登录弹窗界面,在安卓手机(华为畅享z)、pc(window)上能点击输入框正确弹出输入框,而在一些iphone机型上则会出现定位异常问题,比如iphone6sp,点击输入框无法唤出手机输入框,......
  • ICMP timestamp请求响应漏洞CVE-1999-0524解决方法
     ICMPtimestamp请求响应漏洞CVE-1999-0524解决方法1、添加进和出的规则firewall-cmd--permanent--direct--add-ruleipv4filterINPUT0-pICMP--icmp-typetime......
  • docker容器报x509:certificate signed by unknown authority错误
    在执行dockersearch,dockerpull命令时,我遇到的报错信息Errorresponsefromdaemon:Get"https://registry-1.docker.io/v2/":x509:certificatesignedbyunknowna......
  • 图像调色处理软件:Picture Instruments Image 2 LUT Pro for Mac
    想要一款图像调色软件?小编为大家推荐Image2LUTProMac版,一款专业的图像调色小工具。Image2LUTProMac版提供了一些非常有用的选项。除了着色的一般强度,您还可以控制......
  • 第三十五章 Centos7下rpm安装Docker-17.03
    一、安装依赖[root@cos-ftp~]#sudoyuminstalllibxml2-devellibcurl-devel-y二、下载Docker安装包#1.下载地址:https://download.docker.com/linux/centos/7/x86......